Skip to content

Asynchronous members C# 5.0readabilitynew scenarios

Provide `async` and `await` operations to simplify Task-based operations.

Previously in .NET 4.0 you had two choices for long-running or IO operations - either block the current thread until the operation completed (which causes scaling issues) or use callbacks to handle the result (had to read and debug).

.NET 5.0 introduced two new keywords used in conjunction with the Task type to simplify asynchronous programming.

  • async indicates that the declared function should allow await to indicate where it will return control to the caller while the task is running. It does this by returning a Task or Task<T> which indicates the status of the operation and any results.
  • await signals the function should return control to the caller when calling another async Task-based method and it will unwrap the result when it is available. It can only be used inside an async function.

Code

C#
// Using WebRequest for comparison to older styles
var request = WebRequest.Create("https://damieng.com");
var response = await request.GetResponseAsync().ConfigureAwait(false);
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
    Console.WriteLine(reader.ReadToEnd());

// But you're better off using HttpClient, get httpClient from factory/shared instance
var response = await httpClient.GetStringAsync("https://damieng.com");
Console.WriteLine(response);
C#
var request = WebRequest.Create("https://damieng.com");

using (var response = request.GetResponse())
using (var responseStream = response.GetResponseStream()) 
using (var reader = new StreamReader(responseStream))
    Console.WriteLine(reader.ReadToEnd());
C#
var request = WebRequest.Create("https://damieng.com");

Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null)
    .ContinueWith(task =>
    {
        var response = (HttpWebResponse)task.Result;
        using (var stream = response.GetResponseStream())
        using (var reader = new StreamReader(stream))
            Console.WriteLine(reader.ReadToEnd());
    });

Notes

  • Use .ConfigureAwait(false) after any await when you don't need to return to the original context
    • This avoids unnecessary context switching and improves performance and scalability
    • Do not ConfigureAwait in application UI code as the UI must be updated on the original context

More information