Are you awaiting at the right place?

The C# language features async and await are very easy to use, straight forward and available right out of the box in the .NET framework. But it seems the idea behind async & await has some confusions in implementations, especially where you await in the code.

The asynchronous feature boasts about the responsiveness, but it can help boosting the performance of your application as well. Most developers seem to miss this point.

Since most projects start with the Web API, let me start the discussion from there. In a Web API action like below, the async in the action method helps the IIS threads not to be blocked till the end of the call and return immediately, thus increasing the throughput of the IIS.

image

When ever we have an async method developers use the await immediately right there. This makes sense when the rest of the code depends on the result of the call, otherwise this is not a wise option.

Assume we have an async operation like below.

image

Say that you want to invoke the method twice.

image

In the above code snippet, the method is asynchronous – the action method is marked as async, and IIS thread pool returns before the completion and continue from the point where it left when the response arrives.

But the method is not gaining much in the performance, this method would take 12+ seconds to complete. As it goes to the first DoWork() which takes 6 seconds and then the second DoWork() which takes another 6 seconds and finally returns.

Since the result of the first execution is not used or not needed in the rest of the execution we don’t need to perform individual awaits.  We can execute this in parallel.

image

The above code executes the tasks in parallel and awaits at the end of the method. This model would take 6+ seconds.

Async and await are very powerful features of the .NET and they help not only being responsive but also in performance and parallel execution. By using the await carefully you gain more performance advantages.

Advertisement

Asynchronous Programing C# 5.0

C# 5.0 mostly bluff about the asynchronous programming. Of course it has some really kick ass features in the asynchronous programming world.

First of all, asynchronous programing is not new in C# 5.0. It’s been there from C# 1.0, so what’s the big deal now ?

In C# 5.0 they have created a whole new, very tidy and easy programing approach in asynchronous programing. It’s really very tidy.

Here’s a WPF sample application which downloads the headers of an HTTP request and displays in a TextBox. Simply we all know that if we do this without threads our UI will hang until the download operation completes. The solution we’ve been using is threading.

Here I want to make a point; conceptually we all know that using the threads for the above problem will yield the solution for UI unresponsiveness.  But it creates challenges like monitoring the threads and updating the UI, handling exceptions and code untidiness.

Again one more point, when using the threads for the above problem .NET provides various solutions. In Win Forms using the BackgroundWorker is the popular way, in WPF we go for the Dispatcher, we also have our same old IAsyncCallback and delegates mechanism, using the thread pool explicitly, creating and customizing our own threads.

As you see, almost all the above methods are cluttered every where, developers use their own way to handle the problem, not bad but it’s not good either.

And also we have our problems in updating the UI; especially when updating a UI control from a different thread. We get the Cross thread access exceptions.

Here’s the code that shows one way of how the above scenario can be implemented prior to C# 5.0 in WPF.

 private void OldAsyncTechnique()
        {
            SynchronizationContext sync = SynchronizationContext.Current;

            var req = (HttpWebRequest)WebRequest.Create("https://thuruinhttp.wordpress.com");
            req.Method = "HEAD";

            req.BeginGetResponse((asyncResult) =>
            {
                var resp = (HttpWebResponse)req.EndGetResponse(asyncResult);
                sync.Post(delegate
                {
                    TxtHeaders.Text = FormatHeaders(resp.Headers);
                }, null);
            }, null);
        }

Here I get the SynchronizationContext of the current thread, (means the main UI thread) and creates my web request. Then I call the asynchronous BeginGetResponse method of the HttpWebRequest class.

To make the code compact, I called the EndGetResponse in lamda. Using the SynchronizationContext of the UI thread I post the message to the UI control.

But this very complex and I have to pass state object parameters and all. (I have passed null here).

Note : This is not the only way to do this.

 

In C# 5.0 we have new keywords async and await. (You still can enable this in .NET 4 by installing the Async CTP, but since the VS 2012 and .NET 4.5 is released do not waste your time on doing this. You can simply upgrade yourself to .NET 4.5 world)

Here’s the code.

 private async void NewMethod()
        {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("https://thuruinhttp.wordpress.com");
            req.Method = "HEAD";
            HttpWebResponse res = (HttpWebResponse) await req.GetResponseAsync();
            TxtHeaders.Text = FormatHeaders(res.Headers);
        }

Simple as that. You declare the method async and make an awaitable type.

When the code hits the await keyword the method returns immediately, and once the await got the results, the method begins the execution from where it left. Simple theory.

But how it is possible, again that is simple inside C# when you compile the above code, C# compiler rewrites the above code in a fine and an efficient old way.

The real working pattern and how things happen are complex and it used the TPL heavily.

Important : Once you install .NET 4.5 you will get the GetResponseAsync() in the WebClient class. And most classes are enriched with these types of async methods in .NET 4.5. We can have our async and await functionality in our custom classed as well.

Here’s the implementation of the FormatHeaders method.

 private string FormatHeaders(WebHeaderCollection collection)
        {
            StringBuilder builder = new StringBuilder();
            foreach (var s in collection.Keys)
            {
                builder.Append(s + " : ");
                builder.Append(collection[s.ToString()].ToString());
                builder.Append(Environment.NewLine);
            }

            return builder.ToString();
        }