After the birth of Silverlight the developers have had to deal with asynchronous programming much more than before. The responsiveness of the user interface has always been an important matter and asynchronous programming has been the right response also before than Silverlight, in Windows Forms and WPF. But for the first time, Silverlight made a strict request by the framework to run a lot of tasks asynchronous. Due to architectural choices, all the calls to the network API had to be made in an async way, and this caused a number of headaches to developers that for the very first time couldn’t forget about asynchronicity paying the price of a bad user experience.
In metro-style applications, the concept of "make it asynchronous" is exploded to the extreme consequences. WinRT, the underlying wrapper for Windows API, request to run asynchronously most of the tasks, with the rule that, if it may run longer than 50 milliseconds, then it has to be asynchronous. Calling the network, using a device, grabbing a photo from the camera, all these actions are asynchronous in metro-style applications but, async is hidden also behind simpler tasks like opening a message box.
All this surfeit of asynchronous, promises to make programmer’s life a hell. Luckily, the .NET framework 4.5 introduces a set of tools to the rescue, making asynchronous simpler as drinking a glass of water.
The pitfall of asynchronous programming
Just before diving in the new asynchronous model in metro-style applications, it is required we make a step behind and remember why asynchronous is so boring to people. The problem here is matter of context. When you call a synchronous task, all your code runs in a unitary context so, after the task ended, you are in the same context and you can continue the work without any trouble. Differently, an asynchronous task requires a context switch, from a base flow that continues to run, to another flow for the spanned task. So when the asynchronous task ends, your original context has been lost. Let me make a practical example. Let say you have to call a web service to get the list of products for a specific season, and with the result you have to fill an existing Catalog instance; in a synchronous world you will write this code: