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 (hard to read and debug).

C# 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