C# features: async and await

My recent upgrade to Visual Studio 2012 means I now also have the new features in .NET version 4.5 to play with. The one I was most exited about was the async/await pair of keywords introduced to C#. These two keywords aim to offer a relatively simple way of doing asynchronous programming, without all the headaches this sort of thing normally creates. Today I’ll go over the syntax and semantics of these two new keywords.

async

We first look at the async keyword. This keyword is used to mark a method as asynchronous. Consider an example method which returns a number:

public int GetNumber()
{
    // method body
}

If we want to make this method asynchronous, we change its signature to the following:

public async Task<int> GetNumber()
{
    // method body
}

There’s two things to note. First, we’ve added the async keyword to the method signature. But we’ve also changed the return type, by wrapping it in a Task generic. However, we don’t need to change what we return in the method’s body; this would still be just an integer.

await

The async keyword is useless without its counterpart: the await keyword. In fact: any method marked async should have at least one instance of the await keyword somewhere in its body. If it doesn’t, the method will just execute sequentially, without any asynchronicity. The await keyword can only be used inside a method marked async. We expand our example method:

public async Task<int> GetNumber()
{
    Task<int> xTask = SlowMethod();
    int y = FastMethod();
    int x = await xTask;

    return x + y;
}

Now, when GetNumber is called, the asynchronous method SlowMethod is called first, then FastMethod is called, and upon reaching the await keyword the GetNumber method returns control to its caller while it waits for SlowMethod to finish. The idea behind this all is of course that several methods can perform time-consuming operations asynchronously in separate threads, while their callers can keep doing other work and only need to wait for the slower methods to finish once their results are actually needed.

The chicken and the egg

The thing that confused me the most about the async/await keywords is that there seems to be a sort of chicken-and-the-egg problem going on. First, to mark a method async, this method needs to contain at least one await call, which means the method needs to call at least one other method which is also async. Similarly, to call an async method you need to use the await keyword, which you can only do from within an async method. This seems to suggest that whenever you mark some method async, you’ll be forced to spread this asynchronicity up and down this method’s call stack, until your entire program is asynchronous. Right?

Well, fortunately not. On both ends it is possible to end the cycle. Using an asynchronous method from a regular method is done as follows:

public int RegularMethod()
{
    Task<int> task = GetNumber();

    DoOtherThings();

    task.Wait();
    return task.Result;
}

Here, the time-consuming GetNumber method still runs asynchronously while RegularMethod is able to do other things. On the other end of the call stack, here’s how you can call regular methods from an asynchronous method:

public async Task<int> GetNumber()
{
    int y = FastMethod();
    int x = await Task.Run(() => RegularSlowMethod());

    return x + y;
}

Here, the await keyword works just the same, returning control to GetNumber’s caller while RegularSlowMethod executes asynchronously. In fact any Task you can come up with will work with await in this way.