Programming
Raiting:
28

Async and await in C# 5


The recent Visual Studio 11 Beta version has a new and major built-in feature of the future C # 5 - asynchronous programming using async/await. In this article I would like to structure and examine this quite interesting new tool and share the results with you.

Why is it needed?


C# is actively developing language. Each its version has interesting features that really simplify the writing quality of understandable code. For example, Linq considerably simplified the writing of filters for collections and sql queries in the code. Now the turn came for asynchrony.

Even though the framework has accumulated quite a number of ways to write multithreaded code, starting from the manual thread making to the visual component of BackgroundWorker, the development of asynchronous application still requires writing a decent amount of infrastructure code that increases with the complexity of the task. In my opinion the main problem here is the need to change the state of user interface from a background thread (as we know it cannot be done directly).

A new language structure async/await solves this issue by allowing you not only to run a task in a background thread, and when it is completed to execute the code, but also that makes it visually, the code looks almost like a synchronous (including exception handling).

Here is: async/await


In general, the key words are not reflecting the essence clearly enough, but according to the developers nobody came up with better words, so they are what they are. Like most entities in the programming, the new structure is most easily understood directly from the code:

// Synchronous version
private void OnButtonClick ()
{
TextBox.Text = new WebClient (). DownloadString ("http://umumble.com/");
}

// Asynchronous version
private async void OnButtonClick ()
{
TextBox.Text = await new WebClient (). DownloadStringTaskAsync ("http:// umumble.com/");
}

If the synchronous version is simple and clear, then the asynchronous one causes a lot of questions. Let's start with the new method in class WebClient - DownloadStringTaskAsync - this method returns a Task<string> and it is marked as awaitable in the new studio. The type of return value is a key point in this story – but I want to say that await is able to work only with the return functions Task and Task<T>.

So, DownloadStringTaskAsync method creates Task and immediately returns it to the function, while in a background thread is started downloading a page from requested url. We can work directly with the Task object manually, waited until the result is done:

private void OnButtonClick ()
{
Task <string> task = new WebClient (). DownloadStringTaskAsync ("http://microsoft.com/");
task.Wait (); // Here we wait for the completion of task, which blocks the thread
TextBox.Text = task.Result;
}

This code remains synchronous, because we are waiting in the main thread for execution of background ...

There is needed a convenient way to work asynchronously with the task (Task<T>), which remained the only "thread" that connects us with the background thread. And here comes on the scene await that unwinds Task<T> in T, and also it sets up the rest of method in continuation, which is executed after the completion of task in the same thread. Also, this will cause the escape from OnButtonClick () function and the application will continue working in a standard mode, responding to the user actions.
Once the background thread completes its work and returns the result, there will be done continuation in the main thread, which in this case will set up the contents of the page in the text box.

It remains to deal with the keyword async, use this keyword to mark the functions where await will be used. It's simple, and most importantly the compiler will deal with it by not allowing the program to compile, so you will not forget this.

How does it look in operation?


The function can have a few “awaits” that allow creating the asynchronous chains of execution:

private async void StartButtonClick (object sender, RoutedEventArgs e)
{
// Remove the possibility of repressing the button
StartButton.IsEnabled = false;

// Call new task, the execution of this function is over
// rest of function will set up in continuation
TextBox.Text = await new WebClient (). DownloadStringTaskAsync ("http://umumble.com/");
StatusLabel.Content = "Loading a page is completed, processing is beginning";

// in continuation can also be run asynchronous operations with its continuation
var result = await Task <string>. Factory.StartNew (() =>
{
Thread.Sleep (5000) // Simulation of a long processing ...
return "Processing result";
});

// Continuation of second asynchronous operation
StatusLabel.Content = result;
StartButton.IsEnabled = true;
}

What about exceptions? If the developers have promised that the new syntax will be simple and close to synchronous, they could not pass by such an important issue of exception handling. As it was promised, the exceptions that were thrown in a background thread could be handled by using the classic syntax:

private async void StartButtonClick (object sender, RoutedEventArgs e)
{
try
{
TextBox.Text = await new WebClient (). DownloadStringTaskAsync ("http://not-umumble.com/");
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
}

However, there is one thing with the exception handling that you need to understand, because all code that is coming after await is set at the completion, and when it will be completed it is not known at all, then such exception handling will not work:

// This is not working!
private void StartButtonClick (object sender, RoutedEventArgs e)
{
try
{
Download ();
}
catch (Exception ex)
{
MessageBox.Show (ex.Message);
}
}

private async void Download ()
{
TextBox.Text = await new WebClient (). DownloadStringTaskAsync ("http://not-umumble.com/");
}

Download function will return control as soon as the Task will be created with a background thread, and after that will be done the escape from the function StartButtonClick ... and only later in the background thread will be generated an exception that cannot resolve the domain name. A more detailed explanation can be read here.

Conclusion


In the future .Net 4.5 will be added to support the new syntax, namely, there will be many functions that return Task and Task<T>. This new syntax will be simple, therefore, it will receive wide distribution, so there is needed the clear understanding of new language structures, their effects and the fields of use.

Let’s summarize that, the keyword async does not lead to the fact that the method will be executed in a background thread (as it seems from the title), but it only marks that within the present method is await, which works with the Task and Task<T>, so that the rest of the method after await will be executed after the completion of Task in the main thread.

Introducing the new syntax, Microsoft offers more than just the syntactic sugar, but a pattern of asynchronous programming that includes the exception handling, interrupt technique of an asynchronous function, and performance information on the progress ... that is beyond the scope of this article.
MeLavi 28 april 2012, 6:53
Vote for this post
Bring it to the Main Page
 

Comments

Leave a Reply

B
I
U
S
Help
Avaible tags
  • <b>...</b>highlighting important text on the page in bold
  • <i>..</i>highlighting important text on the page in italic
  • <u>...</u>allocated with tag <u> text shownas underlined
  • <s>...</s>allocated with tag <s> text shown as strikethrough
  • <sup>...</sup>, <sub>...</sub>text in the tag <sup> appears as a superscript, <sub> - subscript
  • <blockquote>...</blockquote>For  highlight citation, use the tag <blockquote>
  • <code lang="lang">...</code>highlighting the program code (supported by bash, cpp, cs, css, xml, html, java, javascript, lisp, lua, php, perl, python, ruby, sql, scala, text)
  • <a href="http://...">...</a>link, specify the desired Internet address in the href attribute
  • <img src="http://..." alt="text" />specify the full path of image in the src attribute