WP to W8: Application Framework
|This article is part of a series about my experience porting apps from Windows Phone to Windows 8. Official porting guidance can be found here and don’t forget to follow the Building Windows 8 blog and the Windows 8 App Developer blog for the latest information.
If you are currently working on a Windows 8 app that you’d like reviewed for possible early entry into the marketplace, please contact me.
In this article I’ll talk about the differences in application runtimes between Windows Phone and Windows 8. Windows Phone developers are already comfortable building Silverlight applications and luckily those skills apply equally well to Windows 8. But there’s a powerful new framework called the Windows Runtime (WinRT) that you need to know about, and we also need to understand and write asynchronous code.
When the Windows team was planning the developer story for Windows 8 they were given some hard challenges to solve. Though I haven’t seen the actual design specs, I imagine some of the goals went something like this:
- It must be fast and fluid (to support Metro design)
- It must expose capabilities of the underlying OS in a way that’s both secure and easy to use
- It must be easily accessible in all of the supported languages
- It must feel natural to use in each of the supported languages
- It must provide equal capabilities across all of the supported languages
As you can see from the graphic above, the surface area of WinRT is immense. All four languages are provided with unified APIs for storage, media capture, sensors, GPS and more. With the sheer size of the WinRT and how transparently it’s projected, no wonder developers are mistaking it for the “New .NET”.
So is the .NET framework dead? Not at all. In fact it’s still alive and well with version 4.5 in desktop mode. And though WinRT provides most of the things C# developers need to build Metro style apps, a good chunk of the .NET framework is available in Metro mode too. This can blur the lines between what’s .NET and what’s WinRT, but a good rule of thumb is that WinRT components come from Windows.* namespaces and .NET components come from System.*.
For an in-depth look at leveraging the .NET framework inside Metro style apps, see .NET for Metro style apps overview.
WinRT Components (and WinMD)
Creating a WinRT component is a lot like creating a class library. In fact, class library projects can be converted to WinRT libraries by simply changing the project output from “Class Library” to “WinMD File” (MD stands for MetaData). There are rules that must be followed when creating WinRT components because of the automatic projection system. For example, public methods and properties must only return native WinRT types or basic .NET types like string and int. Private methods and variables, however, can be any .NET type supported in Metro style programs. There are other rules to be aware of, such as how collections are mapped and how to implement asynchronous methods. Luckily, Visual Studio enforces these rules at compile time and even offers instructions on how to correct mistakes if they’re made.
Async and Await
You may have noticed the new await keyword in front of the call to CapturePhotoToStorageFileAsync in the sample above. When you hear the Windows team say ‘Fast and Fluid’ they mean it. And to stand behind that statement they’ve made every single WinRT call that could possibly take longer than 50 milliseconds asynchronous.
But asynchronous programming is hard right? I mean, one can just do a search for “Silverlight asynchronous” and find a long list of developers who were upset coming from the desktop world to find they couldn’t do blocking calls to online services anymore. But developers weren’t upset that they couldn’t block the UI thread, they were upset at how much uglier their code looked and how much harder it was to maintain. To illustrate this problem, consider the following Silverlight code to download a page from a URL:
In this example control flow actually leaves the DownloadPage method and moves to an entirely new method called DownloadStringCompleted. Any data (or state) that existed in the DownloadPage method is not available in DownloadStringCompleted. If a choice needs to be made in the callback based on variables defined in DownloadPage, they have to be promoted to class level variables or somehow passed to the handler.
Anonymous methods and lambdas help this pattern tremendously. For example, we could rewrite our sample above to look like this:
Now the handler is actually inside the DownloadPage method and has access to all its local variables. (This works, by the way, because of a lesser-known feature of modern programming languages called closures.)
The problem with this approach is that it leads to what I like to call “Death by Indention”. For example, if the handler now needs to call something else async, another lambda is required.
And if that handler needs to call another async method, well I think you see the problem. The code is messy and it doesn’t feel natural. We’re even writing what we want to do with the results before we write the lines of code that fetches them! It feels “upside down”. All this work is necessary because we’re asking developers to compensate for the fact that asynchronous methods complete using callbacks.
But what if we could write code that looks like it’s blocking but is actually yielding time while the asynchronous call completes? That’s what the await keyword does and with it our sample can be written like this in Windows 8:
Which one would you rather maintain? 🙂
To learn more about why asynchronous programming is so important on Windows 8 see Keeping apps fast and fluid with asynchrony in the Windows Runtime. To dive deep on how the async keyword works and to learn advanced topics like receiving progress reports, check out the awesome post Diving deep with WinRT and await.
In the next article I’ll start diving into API differences between Silverlight for Windows Phone and the Windows Runtime for Metro style apps.