C# 2012: Anatomy of an Async Method

Excerpt by Joe Mayo | August 27, 2013

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:

public async void StartAsync() { await DoNetworkCommunicationsAsync(); }

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:

using System; using System.Linq; using System.Threading.Tasks; namespace Anatomy_of_an_Async_Method { class Program { static void Main(string[] args) { var prg = new Program(); prg.StartAsync(); Console.WriteLine( "DoNetworkCommunications is running asynchronously."); Console.ReadKey(); } public async void StartAsync() { await DoNetworkCommunicationsAsync(); } public async Task DoNetworkCommunicationsAsync() { Console.WriteLine(DateTime.Now.ToString()); await Task.Delay(3000); Console.WriteLine(DateTime.Now.ToString()); } } }

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.  

JoeMayoThis post is an excerpt from the online courseware for our C# 2012: Asynchronous Programming course written by expert Joe Mayo.

Joe Mayo

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. Joe has written books and contributes to magazines such as CODE Magazine. He has been an active contributor to the .NET community for years, operating the C# Station Web site, authoring the LINQ to Twitter open source project, and speaking regularly at user groups and code camps. For his community contributions, Microsoft has honored Joe with several Most Valuable Professional (MVP) Awards through the years.

This course excerpt was originally posted August 27, 2013 from the online courseware C# 2012, Part 3 of 4: Asynchronous Programming by Joe Mayo