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 method works as follows:ShowFileContents()
- The
method reads the file contents asynchronously and returns aFile.ReadAllLinesAsync()Task<string[]>object. - To show the contents of the file after
method completes, we use theFile.ReadAllLinesAsync()method. Inside the method, we get all the lines of the file in theContinueWith()t.Resultproperty, which is an array of strings. - The method iterates through the lines using a
foreachloop 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 using the ShowFileContentsAsyncasync 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 to complete and get the results as an array of strings.()File.ReadAllLinesAsync
Behind the scenes, the is executed in a separate thread and pauses the File.ReadAllLinesAsync method. Once the ShowFileContentsAsync() completes, it resumes the execution of the ()File.ReadAllLinesAsync method.ShowFileContentsAsync()
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
asynckeyword to mark a method that contains asynchronous operations. - Use the
awaitkeyword inside anasyncmethod to await for aTaskorTask<T>. - The
awaitkeyword pauses theasyncmethod, runs the asynchronous operation in a separate thread, and resumes the execution where it left off. - Always use
asyncandawaittogether. - Always return a
Taskfrom an async method. - Always
awaitan async method to validate the asynchronous operation. - Do use
asyncandawaitall the way up the chain. - Do not use
async voidunless it’s an event handler. - Do not block an asynchronous operation by calling the
ResultorWait()of aTask.