Roadmap › C# Language — Basics to Advanced › Module: Asynchronous and Parallel Programming
Lessons in this course (38)

34. async and await

Intermediate★ Must knowLesson 34 of 38

async/await lets a method wait for I/O without blocking a thread. The compiler rewrites the method into a state machine.

csharp
public async Task<string> GetPageAsync(HttpClient http, string url, CancellationToken ct)
{
    var response = await http.GetAsync(url, ct);   // thread returns to pool while waiting
    response.EnsureSuccessStatusCode();
    return await response.Content.ReadAsStringAsync(ct);
}

// run independent calls concurrently
var t1 = GetPageAsync(http, "https://a.example", ct);
var t2 = GetPageAsync(http, "https://b.example", ct);
string[] pages = await Task.WhenAll(t1, t2);

Rules:

  • Return Task/Task<T> (or ValueTask<T> for hot paths that often complete synchronously). async void only for event handlers.
  • Don't block on async code with .Result or .Wait() — it can deadlock in UI/old ASP.NET contexts and wastes threads.
  • Pass CancellationToken through.
  • In library code, ConfigureAwait(false) avoids capturing the synchronisation context (ASP.NET Core has none).

Interview tip: async is about scalability, not speed. One request doesn't get faster; the server handles more concurrent requests because threads aren't blocked waiting on I/O.