liveBook · Manning

Asynchronous programming

As explained in .NET in Action, Second Edition

Asynchronous programming is a programming technique in which operations can progress without blocking the execution flow while waiting for external work to complete.

Asynchronous programming keeps an application from blocking while it waits for slow work, such as network or disk access. In C#, the Task Parallel Library (TPL) and the async and await keywords provide the main tools. A Task represents work that may run on the same thread or a separate thread; it does not automatically mean a new thread. section 4.4 section 4.5

Consider a title search that requests comic metadata over HTTP. Calling .Result on GetStreamAsync makes each request wait before the search continues. A Stopwatch establishes a baseline: one search took about 35 seconds when requests ran synchronously. The asynchronous approach can start several HTTP requests rather than waiting for each one in turn. Response times still vary; a slow server or throttling can make even a test run take much longer. section 4.3 section 4.4

Listing 4.34 Modifying GetComic to be asynchronous
public static async Task<Comic?> GetComicAsync(            #1
  int number,                                              #2
  CancellationToken cancellationToken)                     #3
{
  if (cancellationToken.IsCancellationRequested)           #4
  {
    return null;
  }
 
  try
  {
    var path = number == 0 ? "info.0.json"
      : $"{number}/info.0.json";
    var stream = await client.GetStreamAsync(              #5
      path, cancellationToken);                            #6
 
    return await JsonSerializer.DeserializeAsync<Comic>(   #7
      stream, cancellationToken: cancellationToken);       #6
  }
  catch (AggregateException e)
    when (e.InnerException is HttpRequestException)
  {
    return null;
  }
  catch (HttpRequestException)
  {
    return null;
  }
  catch (TaskCanceledException)                            #8
  {
    return null;
  }
}

Follow the conversion of a single retrieval method: its async Task<Comic?> return type, awaited HTTP stream and JSON deserialization, and cancellation token passed into both operations. The method also checks for cancellation before starting work and handles request and cancellation exceptions. section 4.4

Making one method asynchronous is only part of the change. The title search also becomes async: it creates retrieval tasks, checks their results for a matching title, and uses a cancellation token so outstanding work can be asked to stop. The calling code must then await the search instead of treating its Task as a completed comic. section 4.4

Listing 4.36 Updating Program.cs to use async method
var results = await Parser.Default                  #1
  .ParseArguments<Options>(args)
  .WithParsedAsync<Options>(                        #2
    async options => {                              #3
      var stopwatch = new Stopwatch();
      stopwatch.Start();
      var comic = await GetComicWithTitleAsync(     #1
        options.Title!);
      stopwatch.Stop();
      // Rest of code continues
    });

The command-line entry point awaits both the asynchronous argument handler and the title search. Stopwatch timing remains around the operation being measured, making the revised search comparable with the synchronous baseline. section 4.4

The same reason to avoid blocking applies to database requests: EF Core work can be performed asynchronously so slow requests need not block application threads. Retries and backoff for slow or throttled responses are separate concerns, not a consequence of adding async and await. section 5.6 section 4.4

How .NET in Action, Second Edition covers it

How deep it goes
Works through Task-based HTTP retrieval, cancellation, concurrent requests, and an awaiting caller; defers retries and backoff.
Examples
Times a synchronous comic-title search, then converts HTTP retrieval and its caller to asynchronous methods.
What it assumes
Assumes familiarity with C# methods and HTTP requests while explaining Tasks and async/await in context.
What you can do after
Apply it via the Task Parallel Library to await HTTP retrieval and avoid blocking during a comic-title search.
How it connects
Connects Tasks, async and await, HTTP requests, JSON deserialization, cancellation tokens, and EF Core database requests.

Also explained in

Compare how 28 books explain asynchronous programming →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of .NET in Action, Second Edition. The section links point to the parts of the book it draws on.