Simple Async Await Example for Asynchronous Programming

LinkedInGoogle+
Back to Articles
Article Image

Stephen Haunts is a Development Manager for a large healthcare retail company, Walgreen Boots Alliance, based in the UK. He is a frequent blogger at www.stephenhaunts.com , a Pluralsight Author , a book author for Syncfusion , a passionate developer and a father. He can be contacted via Twitter @stephenhaunts .

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 been very hard to get right, but it's 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 will issue 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.

Let's 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 50,000 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:

Article Image

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 50,000.

Let's 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 this:

Article Image

Because we have removed the line with the await keyword, the LongRunningMethod() now runs synchronously, so the counter will first count up to 50,000 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 APIs 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<T> . For example, the System.IO.Stream class contains methods such as CopyToAsync, ReadAsync, and WriteAsync alongside the synchronous methods CopyTo, Read, and Write.

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

Resources

LinkedInGoogle+

Comments disabled

All dev articles are now on the TechNet UK Blog where we'd love to receive your comments.

previous

From Hindsight to Insight to Foresight in Cloud Gaming


next

Windows 10 for developers – an independent view

Related
What’s new from the Microsoft Edge Web Summit 2016
What’s new from the Microsoft Edge Web Summit 2016
Testing for quality using Team Foundation Server 2015
Testing for quality using Team Foundation Server 2015
Making your Windows game stand out with Cortana
Making your Windows game stand out with Cortana
Welcoming end of support for IE 8, 9 and 10
Welcoming end of support for IE 8, 9 and 10
How to use Arduino with the Azure IoT hub
How to use Arduino with the Azure IoT hub
Recent
We’re moving home
We’re moving home
Microsoft Developer Monthly News Roundup – July 2016
Microsoft Developer Monthly News Roundup – July 2016
UK team takes on the world at the Imagine Cup
UK team takes on the world at the Imagine Cup
An introduction to the Microsoft Bot Framework
An introduction to the Microsoft Bot Framework
Skyscanner’s Year in Bots
Skyscanner’s Year in Bots
previous

From Hindsight to Insight to Foresight in Cloud Gaming


next

Windows 10 for developers – an independent view