What is new in c# 5.0 – Asynchrone Programming

Today i will hold a talk about “What is new in c# 5.0 – Asynchrone Programming” at the .net usergroup south austria. The agenda is:

  • what is new in c# 5.0
  • async ctp – .net 4.5
  • task based asynchron pattern
  • async – await (Asynchronous Control Flow)
  • async intern
  • synchronisationContext in
  • Console App, Winforms App und Asp.net
  • cancellation
  • exception handling
  • combinators
  • async – await with the Windows Runtime
  • caller information

The powerpoint presentation and the examples are on my public skydrive folder:

What is new in c# 5.0 – Asynchrone Programming


async in the .net framework 4.5

In the developer preview of the .net framework 4.5 the new async feature is included. Microsoft indroduced two new keywords to make asynchronos
programming much easier. This two new Keywords are:

  • async
  • await

It is only possible to use await in a method that is marked with the async keyword. In this simple example the usage of async and await is shown.

 public async void SimpleAsync()
 {
      WebClient webClient = new WebClient();
      await webClient.DownloadStringTaskAsync("http://www.orf.at");
 }

This example shows how the async pattern works. First you have to declare the method as async. If a method is marked as async it is possible to use the await keyword  in it.
If the execution path hits the await keyword it is executing the asynchron operation and imediatly returns to the calling method. If the asynchron operation finished the rest of the method is executed. That means that the compiler is generating a ContinueWith Task for you and puts all statements behind the await keyword in this ContinueWith Task. To do this the compiler generates a state maschine. This statemaschine works similar to the statemaschine the compiler generates if you use the yield statement. The following code comes out of ilspy and shows the code the compiler generates.

public void SimpleAsync()
{
    Program.d__0 d__0 = new Program.d__0(0);
    d__0.4__this = this; 
    d__0.t__MoveNextDelegate = new Action(d__0.MoveNext);
    d__0.$builder = AsyncVoidMethodBuilder.Create();
    d__0.MoveNext();
}

As we see the compiler generates an special class to handle the async execution.

private sealed class d__0
{
    private int 1__state;
    private bool $__disposing;
    public AsyncVoidMethodBuilder $builder;
    public Action t__MoveNextDelegate;
    public Program 4__this;
    private TaskAwaiter<string> t__$await2;
    [DebuggerHidden]
    public d__0(int 1__state)
    {
        this.1__state = 1__state;
    }
    public void MoveNext()
    {
        AsyncVoidMethodBuilder asyncVoidMethodBuilder;
        try
        {
            int num = this.1__state;
            if (num != 1)
            {
                if (this.1__state == -1)
                {
                    return;
                }
                this.t__$await2 = AsyncCtpThreadingExtensions.GetAwaiter<string>(AsyncCtpExtensions.DownloadStringTaskAsync(new WebClient(), new Uri("http://www.weather.gov")));
                if (!this.t__$await2.IsCompleted)
                {
                    this.1__state = 1;
                    this.t__$await2.OnCompleted(this.t__MoveNextDelegate);
                    return;
                }
            }
            else
            {
                this.1__state = 0;
            }
            string result = this.t__$await2.GetResult();
            this.t__$await2 = default(TaskAwaiter<string>);
            this.4__this.WriteLinePageTitle(result);
        }
        catch (Exception arg_AB_0)
        {
            Exception exception = arg_AB_0;
            this.1__state = -1;
            asyncVoidMethodBuilder = this.$builder;
            asyncVoidMethodBuilder.SetException(exception);
            return;
        }
        this.1__state = -1;
        asyncVoidMethodBuilder = this.$builder;
        asyncVoidMethodBuilder.SetResult();
    }
}

So the compiler generates all the importent asynchron code. To execute an asynchron operation you only need to declare an method as async and then you have to tell the compiler on wich operation you want to wait. Befor this operation you put the await keyword and the compiler does the rest.