liveBook · Manning

Async/await

As explained in Pro ASP.NET Core 7, Tenth Edition

The C# await operator asynchronously suspends execution until an awaitable operation completes and produces its result.

In an ASP.NET Core request, an asynchronous operation can give the server more flexibility to schedule other work while it completes. C# uses `async` and `await` to make that operation easier to write without managing a continuation directly. section 5.13 section 5.13.2

A .NET asynchronous operation returns a `Task` representing its eventual result. For example, `HttpClient.GetAsync` returns a `Task<HttpResponseMessage>`. You can attach a `ContinueWith` callback to process the response, but that introduces a lambda and makes the return statements harder to follow. `await` instead gives the next statement the completed result, so the method can read the response and return a value in the usual order. section 5.13.1 section 5.13.2

Listing 5.54 Using the async and await keywords in the MyAsyncMethods.cs file in the Models folder
namespace LanguageFeatures.Models {

   public class MyAsyncMethods {
       
       public async static Task<long?> GetPageLength() {
           HttpClient client = new HttpClient();
           var httpMessage = await client.GetAsync("http://manning.com");
           return httpMessage.Content.Headers.ContentLength;
       }
   }
}

In `MyAsyncMethods.GetPageLength`, `await client.GetAsync(...)` produces the `HttpResponseMessage`; the method returns its nullable `ContentLength`. Because the method uses `await`, its signature includes `async`, but its declared result remains `Task<long?>`. The caller still receives a task, not an immediate length. section 5.13.2

Listing 5.55 An asynchronous action method in the HomeController.cs file in the Controllers folder
namespace LanguageFeatures.Controllers {
    public class HomeController : Controller {
        
        public async Task<ViewResult> Index() {
            long? length = await MyAsyncMethods.GetPageLength();
            return View(new string[] { $"Length: {length}" });
        }
    }
}

An ASP.NET Core controller can follow the same pattern. `HomeController.Index` awaits `GetPageLength()`, then passes the resulting length to a view. Its declared return type is `Task<ViewResult>` because the action is asynchronous. section 5.13.2

For a sequence of results, distinguish `await` on a task from `await foreach` over an `IAsyncEnumerable<long?>`. Awaiting a task that produces a collection makes the controller receive that collection after all its HTTP requests complete; `await foreach` lets it receive each sequence value as it is produced. section 5.13.3

How Pro ASP.NET Core 7, Tenth Edition covers it

How deep it goes
Works through a task-based HTTP request, its continuation-based alternative, and an asynchronous controller action, but defers deeper parallel-programming details.
Examples
Uses an HTTP page-length request, a controller that displays its result, and a multi-URL sequence consumed with await foreach.
What it assumes
Assumes basic C# methods and ASP.NET Core controller structure while explaining Task results and continuation syntax through an HTTP example.
What you can do after
Build it from scratch: write an async HTTP helper and await it from an ASP.NET Core action without using ContinueWith.
How it connects
Connects Task, continuations, lambda expressions, HttpClient, ASP.NET Core controller actions, and asynchronous enumerables.

Also explained in

Compare how 17 books explain async/await →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro ASP.NET Core 7, Tenth Edition. The section links point to the parts of the book it draws on.