After this lesson, you will be able to: Use the Task-based async pattern (async/await) with ConfigureAwait and cancellation tokens.
Async/await in C# is the model TypeScript and Python copied. Once you've used it in C# you'll wonder how anyone writes blocking code.
Mark a method `async`; return Task or Task<T>; await any other async call.
using System.Net.Http;using System.Threading.Tasks;static async Task<string> FetchUserAsync(int id) {using var http = new HttpClient();var response = await http.GetAsync($"https://api.example.com/users/{id}");response.EnsureSuccessStatusCode();return await response.Content.ReadAsStringAsync();}// Calling async from syncvar user = await FetchUserAsync(1); // only valid in async context// Top-level await works in .NET 6+// In libraries / older code, you might see .Result or .Wait(), AVOID, they deadlock in some contexts
Multiple in-flight requests with Task.WhenAll.
// Sequential, slowvar u1 = await FetchUserAsync(1);var u2 = await FetchUserAsync(2);var u3 = await FetchUserAsync(3);// Parallel, fastvar tasks = new[] { FetchUserAsync(1), FetchUserAsync(2), FetchUserAsync(3) };string[] users = await Task.WhenAll(tasks);// First-to-completestring fastest = await Task.WhenAny(tasks).Unwrap();
Standard pattern for cancellable async ops.
using System.Threading;static async Task<string> FetchWithTimeoutAsync(int id,CancellationToken cancellationToken = default) {using var http = new HttpClient();var response = await http.GetAsync($"https://api.example.com/users/{id}",cancellationToken); // propagate the token to the underlying callreturn await response.Content.ReadAsStringAsync(cancellationToken);}// Caller cancels after 5 secondsusing var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));try {var user = await FetchWithTimeoutAsync(1, cts.Token);} catch (OperationCanceledException) {Console.WriteLine("timed out");}
Library code should ConfigureAwait(false) to avoid deadlocks.
// In a library:var data = await http.GetStringAsync(url).ConfigureAwait(false);// Why? Without ConfigureAwait(false), after await, execution resumes on the original// 'sync context' (UI thread in WPF/WinForms; HttpContext in old ASP.NET).// In a library called from such a context, this can deadlock or serialize work.// ConfigureAwait(false) says 'I don't need the original context.'//// In ASP.NET Core, there's no sync context, so ConfigureAwait(false) is a no-op.// In modern app code, you can usually skip it. In library code, always use it.
Calling `.Result` or `.Wait()` on a Task (deadlock + perf loss). Not propagating CancellationToken into nested calls. `async void` outside of event handlers, exceptions silently crash the process. Awaiting in a loop when Task.WhenAll would parallelize.
Sign in and purchase access to unlock this lesson.