VS 2012: Asynchronous Support in C#/VB


If you write a Windows 8 Metro Style app you will use the new WinRT framework (you will use .NET as well if you program in C#/VB). One design principle in WinRT is that every operation that potentially can take more than 50 ms is exposed as an asynchronous method, and only as an asynchronous method. So when you write a Metro Style app, you have to handle asynchronous calls.

All asynchronous methods in WinRT returns one of four interfaces:

  • IAsyncAction, when the method doesn’t have a return value and no progress information is given.
  • IAsyncActionWithProgress<TProgress>, when the method doesn’t have a return value but progress information is given.
  • IAsyncOperation<TResult>, when the method returns a value and no progress information is given.
  • IAsyncOperation<TResult, TProgress>, when the method returns a value and progress information is given.

All these interfaces has a Completed property where you register a completion handler that gets called when the asynchronous method has completed. This completed handler can be implemented as an inline lambda function in all languages Metro Style app supports (C++, C#, VB, JavaScript), but if you have a bunch of asynchronous calls that is dependent on each other, the code can get quite messy.

Enter the async/await feature in C#/VB. Basically what this features does is hide all the asynchronous complexity and let’s you write the code as if it was executed synchronously. An example:

using Windows.Media.Capture;

async void MainPage::TakePhoto_Click(object sender, RoutedEventArgs e) {

  try {

    var dialog = new CameraCaptureUI();

    var file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo);

    var bitmapImage = new BitmapImage();

    using(var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) {

      bitmapImage.SetSource(fileStream);

    }

    Photo.Source = bitmapImage;

  } catch (Exception ex) {

  }

}

Let’s go through the interesting lines of code.

async void MainPage::TakePhoto_Click(object sender, RoutedEventArgs e) {

If we are to use await to wait for a asynchronous operation in a method, we need to mark that method with the async keyword. Also, the method can return two types; either void or Task<T>. Any method that is marked with the async keyword can be waited upon with the await keyword.

var file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo);

Here we call into WinRT to display a user interface that uses the web camera to take a photo and return a file object with that picture. Now, that’s a pretty extremely asynchronous operation, but the code is written as if the method just returns the file. The file object is accessible in the lines of code below as you can see from this line:

using(var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) {

        bitmapImage.SetSource(fileStream);

}

And again we use await to gain “synchronous” access to the filestream variable and uses it in the line after. So we have “synchronous” code doing asynchronous calls that correctly handles everything and doesn’t block the execution on the thread etc. Great! I don’t think anyone can argue that writing asynchronous code is very easy.

But how does it work? Well, it’s no magic. Behind the scenes the compiler generates completion handlers with lambda functions etc., but the beauty of it is that you don’t have to do this yourself. It just works. A wonderful article explaining exactly how this is accomplished under the hood is here. Just love articles like this!

Great, great feature!

 

For all things Metro & Windows 8 development, see our Metro Map here.

 

Happy coding!

/Peter


Comments (0)

Skip to main content