In this article I want to give a simple example for how to use the async await keywords in C# to create asynchronous background tasks.

Writing multi-threaded or asynchronous code has traditionally always been very hard to get right but is something that is needed to help keep our applications responsive and to avoid performance bottlenecks. C# 5 introduced a simplified model for doing asynchronous programming with the introduction of 2 new keywords, async and await.

If you specify that a method is an asynchronous method by using an async modifier, you enable the following two capabilities.

The marked async method can use the await keyword to designate suspension points. The await operator tells the compiler that the async method can’t continue past that point until the awaited asynchronous process is complete. In the meantime, control returns to the caller of the async method. The suspension of an async method at an await expression doesn’t constitute an exit from the method, and finally blocks don’t run.

The marked async method can itself be awaited by methods that call it.

An async method typically contains one or more occurrences of an await operator, but the absence of await expressions doesn’t cause a compiler error. If an async method doesn’t use an await operator to mark a suspension point, the method executes as a synchronous method does, despite the async modifier. The compiler issues a warning for such methods.

Asynchrony is essential for activities that are potentially blocking, such as when your application accesses the web or a file system. Access to a web resource, for example, is sometimes slow or delayed. If such an activity is blocked within a synchronous process, the entire application must wait. In an asynchronous process, the application can continue with other work that doesn’t depend on the web resource until the potentially blocking task finishes.

Lets take a look at a simple example.

using System; using System.Threading.Tasks; namespace AsyncAwaitExample { class Program { static void Main() { var demo = new AsyncAwaitDemo(); demo.DoStuff(); while (true) { Console.WriteLine("Doing Stuff on the Main Thread..................."); } } } public class AsyncAwaitDemo { public async Task DoStuff() { await Task.Run(() => { LongRunningOperation(); }); } private static async Task<string> LongRunningOperation() { int counter; for (counter = 0; counter < 50000; counter++) { Console.WriteLine(counter); } return "Counter = " + counter; } } }

This program contains a class called AsyncAwaitDemo. In this class there is a public method called DoStuff() which launches a long running operation called LongRunningOperation(). This method is marked with the async keyword. For this simple example, the LongRunningOperation() method just counts to 50000 and prints the counter to the console.

Back in our Main() method, after executing the DoStuff() method we then go into an infinite while loop that prints to the console. When you run the program you see something like the following.

What you see here is that the infinite while loop is executing, but the long running task we kick off is also running in the background and counting up to 50000.

Lets modify the code slightly by removing the Task.Run, so that the method looks like the following :

public async Task DoStuff() { LongRunningOperation(); }

If we then run the program we get the following.

Because we have removed the line with the await keyword, the LongRunningMethod() now runs synchronously, so the counter will first count up to 50000 and then the code will go into the while loop.

Avoid Async Void

There are three possible return types you can use for async methods:

Task

Task<T>

void

The main return types for async methods are just Task and Task<T>. When you are converting from synchronous to asynchronous code, any method returning a type becomes an async method returning Task<T>, and any method returning void becomes an async method returning Task.

Async methods that return void have a specific purpose and that is to make asynchronous error handlers possible, but async void methods have different error handling semantics. When an exception is thrown in an async Task or async Task<T> method, that exception is captured and placed directly on the Task object. With an async void method, there is no Task object involved, so any exceptions thrown out in an async void method will be raised directly on the SynchronizationContext that was active when the async void method started. For more information I recommend reading the following MSDN article that has some good examples.

Wrapping Up

In this simple example we used the Task.Run() method to incorporate the await keyword into the code, but .NET framework also provides many async compatible API’s that you can also use with async await. You can recognize these members by the “Async” suffix that’s attached to the member name and a return type of Task or Task. For example, the System.IO.Stream class contains methods such as CopyToAsync, ReadAsync, and WriteAsync alongside the synchronous methodsCopyTo, Read, and Write.

This is a nice and simple example that I hope help you to understand the usage of async / await. It is a flexible and powerful feature of C# 5 and above that should make it much easier for you to write responsive applications.