Async does not make a single request faster.
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)); |