async, await, Task & CancellationToken Masterclass

โšก C# 12 & .NET 8 ๐ŸŸข Chapter 28 of 35 ๐Ÿ“‚ Phase 10: Asynchronous Programming ๐Ÿ“… 2026 Edition
๐Ÿ“Œ Covered in this chapter: Synchronous vs Asynchronous ยท Task & Task ยท async Methods ยท await ยท CancellationToken ยท Task.WhenAll ยท Task.WhenAny ยท Async HTTP Requests

Welcome to Phase 10 (Chapter 28): C# async, await, Task<T>, CancellationToken & Parallel Async Masterclass! Asynchronous programming enables applications to remain responsive while waiting for slow I/O operations (database queries, HTTP calls, file reads). In this lesson, we master Task, Task<T>, async methods, await, exception handling in async, CancellationToken, and parallel async patterns (Task.WhenAll, Task.WhenAny).

1Synchronous vs Asynchronous โ€” Blocking vs Non-Blocking
Synchronous Execution (Blocking Thread): Thread 1: โ”€โ”€[Start]โ”€โ”€[HTTP Request โณโณโณโณโณ]โ”€โ”€[Process]โ”€โ”€[Done]โ”€โ”€ โ–ฒ Thread is BLOCKED and waiting! Wastes CPU! Asynchronous Execution (Non-Blocking Thread): Thread 1: โ”€โ”€[Start]โ”€โ”€[Await HTTP Request]โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€[Process]โ”€โ”€[Done]โ”€โ”€ โ”‚ Thread RELEASED back to thread pool! โ””โ”€โ”€[Disk I/O]โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€[Callback Resumes Thread 1]
C# โ€” Basic async & await Pattern โ–ถ Run in Compiler
// Async method returning Task
static async Task<string> GetMessageAsync()
{
    // await releases the calling thread while Task.Delay runs (simulates I/O)
    await Task.Delay(1000);
    return "Data received successfully!";
}

// Main async entry point (C# 7.1+)
string message = await GetMessageAsync();
Console.WriteLine(message);
2CancellationToken & Task.WhenAll
C# โ€” CancellationToken & Task.WhenAll โ–ถ Run in Compiler
// CancellationToken โ€” Cooperative cancellation mechanism
CancellationTokenSource cts = new CancellationTokenSource(timeout: TimeSpan.FromSeconds(3));

static async Task LongOperationAsync(CancellationToken token)
{
    for (int i = 1; i <= 10; i++)
    {
        token.ThrowIfCancellationRequested(); // Exits cleanly if cancelled
        Console.WriteLine($"Processing step {i}...");
        await Task.Delay(500, token);
    }
}

try
{
    await LongOperationAsync(cts.Token);
}
catch (OperationCanceledException)
{
    Console.WriteLine("Operation was cancelled gracefully.");
}

// Task.WhenAll โ€” Run multiple async tasks in PARALLEL
static async Task Main()
{
    Task<string> task1 = FetchDataAsync("API-1");
    Task<string> task2 = FetchDataAsync("API-2");
    Task<string> task3 = FetchDataAsync("API-3");

    string[] results = await Task.WhenAll(task1, task2, task3);
    Console.WriteLine($"All results received: {results.Length}");
}
3Technical FAQs

Q1: What happens if I don't await an async method?

If you call an async method without await, the returned Task fires and is discarded. Exceptions thrown inside that Task will be unobserved and silently swallowed (or crash the app in some environments).

Q2: What is the difference between Task.WhenAll and Task.WhenAny?

Task.WhenAll completes when ALL provided tasks finish. Task.WhenAny completes as soon as the FIRST task finishes (useful for timeout patterns and cancellation).

Q3: Should I use async/await everywhere?

Use async/await for I/O-bound operations (database, file, network). For CPU-bound heavy computation, use Task.Run() to offload to a background thread pool thread.