Friday, January 30, 2015

Asynchronous Programming using C# Async and C# Await

Asynchronous programming used to be handled using threading in C#. If you had a process you wished to run asynchronously then you just opened up a thread, ran the process on it and then closed it down once the process was complete. Threading however introduces its own set of problems, managing the threads can be tricky and managing the resources applied to them is also a headache.
The Visual Studio Async CTP adds  two new keywords to C# –  await and async which vastly simplify converting asynchronous programming.
Consider the example of a method which calculates the size of URIs passed as a parameter to the method. The method also updates with the size of each file in the list.
public int TotalPageSizes(IList<Uri> uris) {
int total = 0;
foreach (var uri in uris) {
updateText.Text = string.Format("File is {0} bytes ...", total);
var data = new WebClient().DownloadData(uri);
total += data.Length;
}
updateText.Text = string.Format("Total size is {0} bytes", total);
return total; }
It would clearly not be ideal to have this method working off the the main thread of the app since it will prevent anything else from running during that time. This solution could be handled using threading, however, it would be tricky since the thread would be occupied most of the time waiting for a download to complete. With the new await and asynckeywords this can be simply written as below:
public async Task<int> TotalPageSizesAsync(IList<Uri> uris) {
int total = 0;
foreach (var uri in uris) {
updateText.Text = string.Format("File is {0} bytes ...", total);
var data = await new WebClient().DownloadDataAsync(uri);
total += data.Length;
}
updateText.Text = string.Format("Total size is {0} bytes", total);
return total;
}
Firstly note the use of the class Task<T> which was presented in .NET 4.0. The method is now asynchronously  returning a Task<int> instead of an int. The caller of TotalPageSizeAsync can later use the returned Task<int> to determine if the work is complete,  or wait for the int result synchronously or else sign up callbacks to get it when it is ready and complete.
The method also now uses the async keyword to denote it is running asynchronously. Finally (and crucially) the method uses the await keyword for a task which will take some time (in this case downloading the URI) and which we therefore wish to handle asynchronously. Thus when the await keyword is used the code knows to handle that procedure asynchronously, and free up the main thread for other work. Thus if await is not used in a method marked async it will works syncrhonously.

No comments:

Post a Comment