Does async make C# code faster? Throughput, Task.WhenAll and Parallel.ForEachAsync

Async does not make a single request faster.

csharp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// ======================================================================
// Q: Does async make code faster? How do you get better throughput?
//
// Async does not make a single request faster. It frees the thread while waiting
// for I/O, so the server can handle more requests concurrently. For speed within
// one request: run independent calls in parallel.
// - Careful: DbContext is not thread-safe. Don't use Task.WhenAll with queries
//   on the same context.
// - Task.Run inside ASP.NET Core for I/O doesn't help: it just occupies another
//   thread.
// - ConfigureAwait(false) is not needed in ASP.NET Core (there is no
//   SynchronizationContext). In shared libraries it is good practice.
// - ValueTask for hot paths that usually complete synchronously (e.g. a cache
//   hit).
// ======================================================================

// Sequential: 200 + 200 + 200 = ~600 ms
var price = await pricing.GetAsync(sku, ct);
var stock = await inventory.GetAsync(sku, ct);
var eta   = await shipping.GetEtaAsync(sku, ct);

// Parallel: ~200 ms (independent HTTP calls)
var priceTask = pricing.GetAsync(sku, ct);
var stockTask = inventory.GetAsync(sku, ct);
var etaTask   = shipping.GetEtaAsync(sku, ct);
await Task.WhenAll(priceTask, stockTask, etaTask);
var (price2, stock2, eta2) = (await priceTask, await stockTask, await etaTask);

// Batch with a parallelism limit: we don't "flood" the ERP
await Parallel.ForEachAsync(skus,
    new ParallelOptions { MaxDegreeOfParallelism = 8, CancellationToken = ct },
    async (sku, token) => await erp.UpdatePriceAsync(sku, token));