There are two new keywords added to C# for asynchronous programming: async and await. The async keyword is a modifier for methods, delegates, and lambdas to indicate to the C# compiler that a method might contain async code. It also allows other code to call this method asynchronously.
If a method doesn’t contain async code, it executes synchronously, but you will receive a warning message from the C# compiler. To run code asynchronously, use the await modifier when executing a method, anonymous method, or lambda. Here’s an example of using async and await keywords to implement an async method:
<span style="color: #a30000; font: courier; margin-left: auto; margin-right: auto;">public async void StartAsync()
The async modifier indicates that StartAsync can contain async code. The await modifier calls the DoNetworkCommunicationsAsync method and waits for it to complete. In other words, it awaits the method.
Notice the suffix to the StartAsync method is Async. You aren’t required to add the Async suffix to the method name, but it’s a convention that Microsoft recommends and most developers follow in practice. Another tip on naming conventions refers to methods in earlier versions of .NET that implement EAP and already have the Async suffix—you would name them with the TaskAsync suffix.
To make the example simpler, the return type in the previous example is void, but async methods do have return types other than void. For now, let’s defer discussion of the return type until later, which is an important subject of its own.
The previous example doesn’t have any parameters by design in order to keep it simple. However, async methods can have parameters, but none of the parameters can be ref or out.
As in APM and EAP, as soon as the code calls an async method, with the await modifier, control returns to the caller while the method executes asynchronously. Expanding on the previous method, the following code demonstrates a basic example of how async methods work:
<span style="color: #a30000; font: courier; margin-left: auto; margin-right: auto;">using System;
static void Main(string args)
var prg = new Program();
"DoNetworkCommunications is running asynchronously.");
public async void StartAsync()
public async Task DoNetworkCommunicationsAsync()
Let’s look at what this code shows in terms of control or what is running when. The specific threading model is defined separately for each .NET technology by a type derived from SynchronizationContext, but this is beyond the scope of this course.
The Main method calls the StartAsync method. Because StartAsync is modified as async, the code will run synchronously until it encounters a call to an async method with the await modifier. As soon as the code calls the method with await, control returns to the calling code Main. So you have two methods running at the same time—Main and StartAsync.
StartAsync continues by calling the DoNetworkCommunicationsAsync method. However, the await modifier makes StartAsync wait until DoNetworkCommunicationsAsync completes. When DoNetworkCommunicationsAsync completes, StartAsync ends. Control was already returned to Main when it encountered the await call to DoNetworkCommunicationsAsync, so StartAsync does not return at the end of the method, it just stops running.
That means that inside of StartAsync, all the code above the awaited method will run synchronously. At the same time, the async method runs. When
DoNetworkCommunicationsAsync completes, control returns to StartAsync and any code following StartAsync executes.
Joe Mayo is an author, independent consultant, and instructor specializing in Microsoft .NET and Windows 8 technology. He has several years of software development experience and has worked with .NET since July 2000.