Friday, August 24, 2012

WinRT, Async, and .Net

I'm loving WinRT so far.  It's a beautiful way to develop modern apps.  It's the biggest and best change to come to developers in some time.  I won't talk about lock-down, the Windows Store, or Windows 8 paradigm shifts in general today, but I will talk about WinRT, Async, and .Net!

The Async Framework came before WinRT of course, but its amazing integration has come with the new framework.  I love the fact that all of the potentially blocking methods are now exposed as asyncronous methods.  The IAsyncOperation return type, which is returned from these methods, can be easily awaited to avoid the hassle of callbacks, and for .Net integration, you can always use the AsTask() extension method (though you'll often not need to).

Background operations often require two important things: the ability to cancel them from other threads, and the ability to report progress.  Both of these needs are easily addressed using the CancellationToken object and IProgress<> interface.  Strangely, from .Net you need to first get the Task adapter, but then you can just pass the CancellationToken to operations, and then call Cancel() method from another thread (often the UI thread).

Progress is a little bit trickier since most framework methods don't have direct support for it.  Adding progress reporting to your own methods is almost trivial though.  Instead of being limited to simple integer-based progress (like in the older BackgroundWorker class), you can use anything you want since you create your progress handler with a generic type.  You can simply return a string to directly display, a number out of 100, or a complex custom object that reports per-item, batch-level, and other information in each report, then write your own code for what to do when the reports come in.

Handling cancellation in your own methods works one of two ways: you can either check to see if cancellation has been cancelled and clean up before throwing the TaskCanceledException, or call the ThrowIfCancellationRequested() method if you don't have any last requests.

The await and async keywords are some amazing compiler trickery.  Having written callbacks for asynchronous code for years, it's so refreshing.  There's just a tiny bit of mind-bending the first time, but the picture becomes clear pretty quickly!  Basically, ignore the async part of it all unless you have special needs. You can always choose not to await, or to wait on more than one operation to complete, or to wait until the first of a group of operations completes, but even these special cases don't really mess things up.  Once you learn the new commands you'll be productive quickly.

It's funny.  Thinking through how the async features work with return values, exception handling, and the generated state machines, it's not that hard to imagine making it work from scratch.  Of course, things are always so much more obvious once you see how they work!

I have some videos coming out soon that walk through some async scenarios.  I'll post the links then.  In the meantime, grab Windows 8 and Visual Studio 2012 and start figuring it out!