C# async/await

Summary: in this tutorial, you’ll learn how to use the C# async/await keywords for asynchronous programming.

Introduction to C# async/await keywords

The following method reads a text file asynchronously and outputs its contents on the console:

class Program
{
    static void ShowFileContents(string filename)
    {
        var task = File.ReadAllLinesAsync(filename);

        task.ContinueWith(t =>
        {
            var lines = t.Result;
            foreach (var line in lines)
            {
                Console.WriteLine(line);
            }
        });

    }


    static void Main()
    {
        ShowFileContents("C:\\temp\\readme.txt");
        Console.Read();
    }
}Code language: C# (cs)

How it works.

First, define the ShowFileContents() method that takes a string parameter filename. The filename parameter specifies the path to the file to be read.

The ShowFileContents() method works as follows:

  • The File.ReadAllLinesAsync() method reads the file contents asynchronously and returns a Task<string[]> object.
  • To show the contents of the file after File.ReadAllLinesAsync() method completes, we use the ContinueWith() method. Inside the method, we get all the lines of the file in the t.Result property, which is an array of strings.
  • The method iterates through the lines using a foreach loop and displays each line to the console.

Second, define the Main() method as the main entry point of the program.

The Main() method uses the ShowFileContents() method to read the readme.txt file from the C:\temp directory and display its contents to the console.

The program works fine. But the code is quite verbose and somewhat difficult to follow. To make it more simple, C# introduces the async/await keywords.

When a method is marked with the async keyword, it contains asynchronous operations which are executed on a separate thread. This allows the method to return immediately without blocking the calling thread.

The async methods need to have an await keyword in their body. The await keyword waits for the completion of an asynchronous operation before continuing the current execution.

Also, you can use the await keyword to wait for a Task or Task<T> object. The await keyword pauses the async method until the asynchronous operation completes and resumes the execution from where it left off.

Notice that the await keyword is only valid inside an async method.

The following example converts the above program to the one that uses the async/await keywords.

class Program
{
    static async Task ShowFileContents(string filename)
    {
        var lines = await File.ReadAllLinesAsync(filename);

        foreach (var line in lines)
        {
            Console.WriteLine(line);
        }
    }

    static async Task Main()
    {
        await ShowFileContents("C:\\temp\\readme.txt");
        Console.Read();
    }
}
Code language: C# (cs)

How it works.

First, mark the ShowFileContentsAsync using the async keyword. It indicates that the method contains asynchronous operations. By convention, an async method has the Async suffix.

Second, use the await keyword to wait for the method File.ReadAllLinesAsync() to complete and get the results as an array of strings.

Behind the scenes, the File.ReadAllLinesAsync is executed in a separate thread and pauses the ShowFileContentsAsync() method. Once the File.ReadAllLinesAsync() completes, it resumes the execution of the ShowFileContentsAsync() method.

Third, use a foreach loop to display each line in the lines array to the console.

Finally, mark the Main() method as an async method and use the await keyword to wait for the ShowFileContentsAsync() method to complete.

As you can see, the async/await keyword simplifies the code for asynchronous programming.

Summary

  • Use the async keyword to mark a method that contains asynchronous operations.
  • Use the await keyword inside an async method to await for a Task or Task<T>.
  • The await keyword pauses the async method, runs the asynchronous operation in a separate thread, and resumes the execution where it left off.
  • Always use async and await together.
  • Always return a Task from an async method.
  • Always await an async method to validate the asynchronous operation.
  • Do use async and await all the way up the chain.
  • Do not use async void unless it’s an event handler.
  • Do not block an asynchronous operation by calling the Result or Wait() of a Task.
Was this tutorial helpful ?