Home > Development, Mobile > WP to W8: Application Framework

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.

 

WinRT

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

 

Those are some pretty lofty goals, especially when you consider that the languages Microsoft wanted to support included C#, VB, C++ and JavaScript. To my knowledge no framework has ever been created that provides equal capabilities and feels natural to use across so many languages. But that’s exactly what the product team did when it created the Windows Runtime (WinRT).

To C++ developers WinRT looks a lot like a C++ library that’s been linked to the project. To JavaScript developers WinRT looks a lot like an external .js file that’s been referenced. To C# and VB developers WinRT feels a lot like the .NET framework. In fact it feels and looks so much like .NET that if you don’t know exactly what to look for you might just assume it is. This caused some confusion at our //build conference and is still a point of confusion for many developers today, so I’d like to try and demystify it a little for those of you coming from Windows Phone. The truth is that WinRT is actually closest to what the C++ developer sees. WinRT is a runtime, created by the Windows team, written in C++ and exposed to all four languages in a natural way. This is probably easiest to understand by looking at a code sample (or three).

 

C++
ImageEncodingProperties^ imageProperties = ref new ImageEncodingProperties();
imageProperties->Subtype = "JPEG";
imageProperties->Width = 320;
imageProperties->Height = 240;     

auto opCapturePhoto = m_mediaCaptureMgr->CapturePhotoToStorageFileAsync(imageProperties, this->m_photoStorageFile);  

 

C#
ImageEncodingProperties imageProperties = new ImageEncodingProperties();
imageProperties.Subtype = "JPEG";
imageProperties.Width = 320;
imageProperties.Height = 240;

await mediaCaptureMgr.CapturePhotoToStorageFileAsync(imageProperties, photoStorageFile);

 

JavaScript
var photoProperties = new Windows.Media.MediaProperties.ImageEncodingProperties();
photoProperties.subtype = "JPEG";
photoProperties.width = 320;
photoProperties.height = 240;

mediaCaptureMgr.capturePhotoToStorageFileAsync(photoProperties, photoStorage).then(…

 

The code snippets above are from the MSDN Sample Media capture using webcam. These 5 lines of code turn on the web cam, capture an image, resize it to 320 x 240 and save it as a file in JPEG format. (Yes, you really can use the webcam and save local files using JavaScript – assuming the user has given your app permission to of course.)

Notice that the 5 lines of code use the same object names and property names whether you’re using C++, C# or JavaScript. And notice that the name casing changes from Title Case for C++ and C# to camel Case for JavaScript. This ability of the WinRT to “morph” into your language of choice is called Projection and it’s pretty amazing. The WinRT is written in C++ to be as fast as possible, but its objects and capabilities can be used in all supported languages just as if the WinRT were written natively in that language.

image

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)

Now that you know what the WinRT is and how projection works, you might be thinking “Wouldn’t it be cool if I could create my own WinRT libraries and sell them or share them with other developers?” Well you can, and they can be written using C++, C# or Visual Basic. Though you can’t author WinRT components using JavaScript today, components created in any of the other languages are automatically projected and are usable by all of the languages – including JavaScript.

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.

You can read all of the rules and requirements in the article Creating Windows Runtime Components in C# and Visual Basic. Keep in mind that .NET class libraries are still supported, so if you aren’t looking to interop with C++ or JavaScript you may not need to create a WinRT component at all. If WinRT is what you need, be sure to check out Creating a simple component in C# or Visual Basic and calling it from JavaScript.

 

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:

private void DownloadPage()
{
    WebClient client = new WebClient();
    client.DownloadStringCompleted += DownloadStringCompleted;
    client.DownloadStringAsync(new Uri("http://www.bing.com"));
}

private void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    // Only proceed if there wasn't an error
    if (e.Error == null)
    {
        …
    }
}

 

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:

private void DownloadPage()
{
    WebClient client = new WebClient();
    client.DownloadStringCompleted += (o, e) =>
        {
            // Only proceed if there wasn't an error
            if (e.Error == null)
            {
                …
            }
        };
    client.DownloadStringAsync(new Uri("http://www.bing.com"));
}

 

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.

private void DownloadPage()
{
    WebClient client = new WebClient();
    client.DownloadStringCompleted += (o, e) =>
        {
            // Only proceed if there wasn't an error
            if (e.Error == null)
            {
                WebClient client2 = new WebClient();
                client2.DownloadStringCompleted += (o, e) =>
                    {
                        // Only proceed if there wasn't an error
                        if (e.Error == null)
                        {
                            …
                        }
                    };
                client2.DownloadStringAsync(new Uri("http://www.microsoft.com"));
            }
        };
    client.DownloadStringAsync(new Uri("http://www.bing.com"));
}

 

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:

private async void DownloadPage()
{
    HttpClient client = new HttpClient();
    string bing = await client.GetStringAsync("http://www.bing.com");
    string ms = await client.GetStringAsync("http://www.microsoft.com");
}

 

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.