C# Tutorial · Advanced C# · Lesson 20 of 22
C# Async and Await
Task, async/await, Task.WhenAll and cancellation.
async and await
I/O-bound work — HTTP calls, database queries, file access — should be asynchronous so threads aren't blocked waiting. An async method returns Task or Task<T>; await waits without blocking:
using System.Diagnostics;
static async Task<string> FetchAsync(string name, int ms)
{
await Task.Delay(ms); // pretend to call an API
return $"{name} done";
}
var sw = Stopwatch.StartNew();
Console.WriteLine(await FetchAsync("first", 100));
Console.WriteLine(await FetchAsync("second", 100));
Console.WriteLine($"sequential ≈ {Math.Round(sw.ElapsedMilliseconds / 100.0) * 100} ms");
sw.Restart();
string[] results = await Task.WhenAll(FetchAsync("a", 100), FetchAsync("b", 100), FetchAsync("c", 100));
Console.WriteLine($"{string.Join(", ", results)}: parallel ≈ {Math.Round(sw.ElapsedMilliseconds / 100.0) * 100} ms");
using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(50));
try { await Task.Delay(1000, cts.Token); }
catch (TaskCanceledException) { Console.WriteLine("cancelled after timeout"); }
Output
first done second done sequential ≈ 200 ms a done, b done, c done: parallel ≈ 100 ms cancelled after timeout
Run this on your computer — see “Get Started” for setup.
Rules of thumb
- Make it async all the way: don't call
.Resultor.Wait()(deadlocks and blocked threads). - Pass a
CancellationTokenthrough async calls so work can stop early. - Use
Task.WhenAllfor independent operations.
Test yourself
What does an async method that returns a number have as its return type?
intTask<int>async intPromise<int>
Show answer
Answer: Task<int>