WinRT, the Windows Runtime, was launched by Microsoft to some puzzlement. How does it relate to COM? Is it a replacement for .NET or SilverLight? Is it the same as Windows RT? Why is it important? Michael answers these questions and more.
What is the Windows Runtime?
The Windows Runtime (‘WinRT’) is the most recent programming interface into the Windows operating system. It first appeared in the Windows 8 family of OSs and a variant of it has since appeared in Windows Phone 8. WinRT is easily confused with Windows RT, the name of the version of Windows 8 that runs on ARM-based tablets and computers. In this article, WinRT will always mean the Windows Runtime. WinRT has roots both in COM and .NET. To understand where it came from, it helps to understand a little about where COM and .NET themselves each came from.
There once was a dream: A dream of a platform where a programmer could write a useful object (for fun, profit, or both) and share it with other programmers. Those programmers could use that object in their own projects, either to build more complex objects or to build whole computer programs. And none of these programmers would need to know or care what programming language any of the other programmers used. This was the dream that launched COM.
COM is a component-based architecture that is based on the object-oriented paradigm. It lets programs use objects without knowing their internal implementation details. Indeed, a program doesn’t even need to be written in the same programming language as any COM objects it uses. To create and use a COM object , the program only needs to know the object’s interface, the interface’s id (a GUID), and an implementing object’s class id.
That’s the theory, anyway. COM eventually evolved to deliver most of what its designers intended, but in a lot of ways COM was too far ahead of its time when it was developed. Writing simple COM code was rarely simple, and writing complex COM code was often a tortuous task. Programmers who could write correct COM code and successfully debug and fix incorrect COM code were in high demand as a result. And while COM objects could, in theory, be created and used in any programming language, in practice they were usually written in C++ and used in either C++ or Visual Basic programs (the original VB, before .NET).
Time passed, programming language design evolved, and .NET was born..NET was able to improve on certain aspects of COM in pursuit of its goal of seamless interoperability between objects. It used a system of metadata in place of COM’s complicated IDL and TLB files. This system vastly simplified the creation of .NET objects. Where COM had many different types for the same purpose (e.g. for strings), .NET had one (e.g. System.String).
But interoperability between .NET and non-.NET code was complicated. .NET was designed for to be easy to use and not to have the memory leaks that plagued programs at the time it was developed. It adopted the automatic memory management model known as ‘garbage collection’. A special object, the GC, does all the heap allocations for the program and tracks all references to those objects that it has allocated. Periodically, the GC does a collection wherein it finds all objects that are no longer reachable by the program and destroys them, releasing their memory for future use. As a by-product of how the GC works, it also performs heap compactions at times in order to create larger blocks of free memory. This compaction will result in an object’s memory address being liable to change at any time. This doesn’t matter to .NET programs because whenever the garbage collector does a compaction, it patches things up where it needs to. But it matters very much to non-.NET programming languages since they have no way of knowing that the object moved and thus will continue to look for it at that old address. This is one of several issues that make it is impossible to use .NET to realize the dream of seamless interop without regard to language.
Thus we get to the origins of WinRT. At its core, WinRT looks like an improved, simplified COM merged with the .NET metadata system (in place of COM’s old system of CLSIDs, IIDs, IDL files, and TLB files). By using COM’s interface-based design, WinRT’s designers were able to deliver a level of language-agnostic interop that .NET could not achieve. By using .NET’s metadata format and borrowing other design features from .NET (such as a single string type and making it possible for an object to know its own type at all times), they avoided the complexities that made using COM very difficult for most programmers. Shucked of COM’s lesser used features and burnished by a type and metadata system closely resembling .NET, WinRT delivers all of the important aspects of the dream that launched COM.
How does WinRT relate to .NET?
WinRT is a companion to .NET. Because its metadata system is almost the same as .NET’s metadata system and it uses base types that map closely to .NET types, the two runtimes work together as partners (perhaps even friends, to the extent that bits and bytes can form friendships). (Ed: maybe just a bit on the side?)
WinRT provides a sandboxed application model. While .NET has had sandboxed apps before (Silverlight), the restrictions needed to accomplish the sandboxing all but shut down access to the system. Users had to decide low-level issues such as whether or not they trusted a Silverlight app to be allowed to use hardware graphics acceleration. Many other capabilities were simply denied to the app altogether. While WinRT still restricts what an app can do, because it was designed from the ground up to be an OS API with sandboxing, it was possible for the designers to grant apps many more capabilities (e.g. sharing data and files between apps).
WinRT also adopts asynchrony, which works wonderfully with .NET 4.5’s async and await features. The wait cursor (once represented as an hourglass and later a spinning disc, but always a source of annoyance regardless of form) is something users of WinRT apps should rarely encounter and even then only for a few moments. Instead, operations that could potentially run for a long time are moved off the UI thread to keep applications responsive to user input even as files are being loaded or data is being streamed across a network.
Most often overlooked is that WinRT is a companion for .NET. It’s not a replacement and you shouldn’t expect Microsoft to be prying WPF, ASP.NET, Win Forms, or any other .NET technology from your hands because it’s not going to happen. While apps built for the Windows Store or for Windows Phone 8 make use of WinRT APIs, desktop apps, web sites and applications, WCF services, and other .NET projects will continue to play a role for many years to come.
So what happened to Silverlight then?
What is interop like with WinRT?
I wrote an article here on Simple-Talk about interop entitled 5 Tips for Understanding Managed-Unmanaged Interoperability in .NET. The good news? You don’t need to understand any of it to use WinRT components. (The bad news? You still need to understand interop for non-WinRT interactions between managed and unmanaged code.)
A native C++ programmer can use a WinRT component written by a VB programmer with no special magic needed. The same is true for a C# programmer using a native C++ WinRT component and any other mix and match of those languages (plus any other languages that programmers can author WinRT components in).
Indeed, because developers in these non-.NET languages can use your .NET WinRT components, if you are a component vendor, your potential client base expands dramatically with WinRT. And if and when other languages gain WinRT support, your components will just work in those languages too. The same is also true for C++ WinRT component developers.
What pitfalls do I need to know about with WinRT and .NET?
Surprisingly, there aren’t many pitfalls to using WinRT with .NET. The major one is a side-effect from WinRT using what is called language projections.
Language projections go farther than just appearance changes, though. WinRT types that have a similar type in the target language are projected to appear to be that type. So the low level WinRT string type, HSTRING, appears in .NET as being a System.String. For the most part this causes no problems. But there are some things to note.
Much of the System.Type class functionality now appears in the System.Reflection.TypeInfo class, for example. Also WinRT has a reduced subset of exception classes compared with .NET so in places where you might have caught, e.g., a System.UriFormatException, because that type of exception doesn’t exist in WinRT, you instead catch its parent, System.FormatException. Not all .NET types are supported in WinRT, and for those that are, some of their members (especially extension methods) may not be available (see, for example, System.String). For a good overview of all of these issues, see: .NET for Windows Store apps overview.
At its core, WinRT uses reference counting to manage the life span of most WinRT objects. If this sounds a lot like COM, it’s because it is like COM. WinRT classes implement COM’s IUnknown interface. Strictly speaking, they are required to implement an interface called IInspectable, which derives from IUnknown. IInspectable was created for WinRT in order to give objects the ability to know what type they are and what interfaces they implement. This is all part of the machinery that enables the .NET-like metadata and type systems. The .NET CLR is aware of WinRT’s reference counting and handles it for you. So you don’t need to do anything special here.
Some WinRT types have a Dispose method. Just like with any .NET object that implements IDisposable, it’s important to use the using statement with these types in order to ensure that any unmanaged resources are freed deterministically (i.e. right away) rather than remaining allocated until the GC gets around to freeing them (which can cause exceptions if you try to re-access certain resources, such as files, before the GC has freed them).
Why should I learn WinRT?
Over 100 million Windows 8 licenses were sold as of May 6, 2013, just a little over six months since its launch. Windows 8.1, a free update, is set to launch in Fall 2013, resolving most, if not all, of the complaints some users have had about Windows 8.0. PC manufacturers have been steadily rolling out great new touch-enabled tablets, convertibles, laptops, and all-in-ones. With many improvements to the OS combined with great hardware, holiday 2013 should see a healthy addition to the already large install base of Windows 8 devices.
Windows Phone is growing slowly but steadily. Microsoft continues to deliver great new developer education content while working behind the scenes on updates and improvements to the platform. Like with the original Xbox, Microsoft shows every sign of being willing to play the long game with Windows Phone if necessary.
Nobody who can talk about it knows too much about the three OSes that the Xbox One (the successor to the Xbox 360) will run. One is said to be designed for games, one is believed to be a modified version of Hyper-V, and the last is believed to be a customized version of the Windows 8 kernel. The last OS is widely believed to include a variant of WinRT.
Given all of this, there really isn’t much of a question left. Learning WinRT gives you access to awesome platforms with great commercial potential. It also opens the door to the potentially lucrative field of WinRT component development. Best of all, because of how easily WinRT integrates into .NET, the learning curve is quite shallow. So what are you waiting for?
Is COM Dead?