Visual Studio Async CTP Overview

The new Microsoft Visual Studio Async CTP proposes a new language feature in C# and VB, and a new framework pattern to go with it, that will make asynchronous programming similar to and almost as straightforward as synchronous programming.

For most .NET operations there is both a synchronous  and an asynchronous  way of doing things. The problem is that these current patterns can prove disruptive to program structure, leading to complex and error prone code or that developers just give up and use the blocking approach, sacrificing UI responsiveness or performance.

The goal of these new language features is to bring the asynchronous development experience as close to the synchronous one as possible, without sacrificing the ability to handle  async-specific situations.  The people at Microsoft understand that asynchronous code blows up your control flow. The "call you back" part needs a callback – a delegate describing what comes after. But the approach is limiting.   What if you wanted to "wait" inside a while loop, or an if statement? You have a control - flow problem.

The new approach utilizes Tasks and two new keywords, async, and await. As a result, your asynchronous code will now look virtually identical to its synchronous version, with the compiler taking care of creating and signing up the callbacks.

An example from the CTP Whitepaper illustrates this new simplicity:

public async Task<int> SumPageSizesAsync(IList<Uri> uris) {
    int total = 0;
    foreach (var uri in uris) {
        statusText.Text = string.Format("Found {0} bytes ...", total);
        var data = await new WebClient().DownloadDataAsync(uri);
        total += data.Length;
    }
    statusText.Text = string.Format("Found {0} bytes total", total);
    return total;
}

What the above code does is to return a Task<int> which allows the caller to use the returned Task<int> to inquire whether the work is complete, wait for the int result synchronously or sign up callbacks to get it when it is ready. This provides needed simplicity and  also allows for a mindset which promotes a more comprehensible control flow. The marking of the method with the async keyword means that the method body is compiled specially, allowing parts of it to be turned into callbacks, and automatically creating the Task<int> that is returned.

The "await" keyword in the var data = await new WebClient().DownloadDataAsync(uri); line looks like it is a blocking call, but it isn't. Instead it signs up the rest of the method as a callback on the task, and immediately returns. When the awaited task eventually completes, it will invoke that callback and thus resume the execution of the method right where it left off.

The Task and Task<TResult> types are already in .NET Framework 4. A Task represents an ongoing activity, which would usually be CPU intensive work running on a separate thread, but it can also represent an I/O operation, for example waiting on a  response from a web request. Task by itself represents an activity without a result, and Task<TResult>, represents an activity with a result of type TResult (in the example case, an int representing the sum of all the page sizes).

The simplest implementation of use of the Task construct might look like this:

Task<double> task = Task.Run(() => LongRunningComputation(x, y, z));

This schedules the work  represented in the lambda on a Threadpool thread, immediately returning a task that will complete when the work is done. The caller can check the Status, IsCompleted, and / or IsCanceled properties.

By returning a Task or Task<T> as in the Whitepaper example above, only one method is needed, and all further interaction with the future result is done through the Task object.

Async methods by themselves do not run on their own thread. If you write an async method without any await’s in it, it will be completely synchronous. Only when an async method gets to the first await does it return to its original caller, and only then until it await’s a task that is not yet complete. If you want to get intensive work or blocking calls off your thread, you should explicitly put them on the thread pool using Task.Run.

The AsyncCtpLibrary assembly has a new Type "TaskEx" with various methods such as Run, Delay, RunEx, WhenAll, etc.

In Anders Hejlsberg's RSS Feed Aggregator sample (one of the samples in the CTP download), there are two different ways to get the feeds asynchronously:

  
  // using parallel:
  var feeds = new string[urls.Count];
  Parallel.For(0, urls.Count, i => feeds[i] = CreateWebClient().DownloadString(urls[i]));

   // using async:
var feeds = await TaskEx.WhenAll(from url in urls select CreateWebClient().DownloadStringTaskAsync(url));

Async methods can be explicitly written to be "fire and forget" – by returning void instead of Task or Task<TResult> from the method.

The Task type also offers an easy way to get parallelism. With a collection of tasks, you can call Task.WhenAll to obtain a task that completes when all of the constituent tasks have completed. They will run concurrently and take advantage of multiple cores.

You can download the Visual Studio Async CTP here:

It has a full suite of over two dozen samples in both C# and VB.NET  including Silverlight, WinForms, and WPF  applications. There is even an options pricing example using Excel.

In sum, The Visual Studio Async CTP combines a new simple and composable pattern for asynchronous APIs, with "await" and "async" language keywords in Visual Basic and C#, that avoids asynchronous code having to be written "inside-out" using callbacks. The CTP is a painless install/uninstall on top of Visual Studio 2010 RTM, and comes with plenty of samples and documentation.  The single AsyncCtpLibrary assembly is just 104Kb, and the Silverlight version only 132Kb.  Recommended, because it's pretty likely you'll see this in C# 5.

By Peter Bromberg   Popularity  (5173 Views)