C# 5 asynchronous programming

If you missed Anders Hejlsberg talk on the Future directions for C# and Visual Basic, go check it out now, I’ll wait.

I hope you'll agree that asynchronous programming just got a whole lot easier to do. The point that Anders made that really cemented in my mind how the new async and await C# keywords work in practice was this:

public async Task<XElement> GetXmlAsync(string url)
{
    var client = new HttpClient();
    var response = await client.GetAsync(url);
    var text = response.Content.ReadAsString();
    return XElement.Parse(text);
}

which is effectively translated to the following

public Task<XElement> GetXmlAsync(string url)
{
    var tcs = TaskCompletionSource<XElement>();
    var client = new HttpClient();
    client.GetAsync(url).ContinueWith(task =>
        {
            var response = task.Result;
            var text = response.Content.ReadAsString();
            tcs.SetResult(XElement.Parse(text));
        });

    return tcs.Task;
}

Something about this feels particularly familiar. If you’ve written any type of web application that utilizes AJAX, writing callback functions in JavaScript (or more likely, using a JavaScript library) happens all over the place. You know that when you see this

function updatePerson() {
  var returnedMessage;

  $.ajax({
     type: "POST",
     url: "people/update/2",
     data: { firstName : 'John', secondName : 'Smith'  },
     success: function(msg){
       returnedMessage = msg;
     }
   });

  return returnedMessage;
}

that returnedMessage will be undefined until the request made via AJAX returns and returnedMessage is set to the value of msg  returned from the server. This is a common mistake that people make when first using JavaScript to make AJAX requests and may have been some of the impetus behind the introduction of $.Deferred() in jQuery 1.5. If you wanted the above to work as intended and perhaps be a little clearer, you could rewrite it as

function updatePerson() {
  return $.ajax({
     type: "POST",
     url: "/people/update/2",
      data: { firstName : 'John', secondName : 'Smith' }
   }).promise();
}

updatePerson().done(function(msg) {
   // do something with msg
});

This returns a promise that provides a view onto the current state of the task and allows the addition of further callbacks. Here’s a demo from jsfiddle:

Continuation Passing Style, as it is known, is not a new topic and is one that is most familiar to those engrossed in functional programming languages. If you want to read more about it, Eric Lippert wrote a great series of posts on the subject some time ago and if you’re interested in knowing more about how the new C#5 asynchronous programming works under the hood, go check out Jon Skeet’s Eduasync series. Understanding these well now will mean that one will be able to put them to good use as soon as they’re officially released to market.

Comments

comments powered by Disqus