C# Task.WhenAll — Complete Guide
In this tutorial, you'll learn about C# Task.WhenAll. We cover key concepts, practical examples, and best practices.
You need to download three files, query two databases, or call four APIs. You await each one sequentially, adding the latencies together. Task.WhenAll runs them concurrently, completing when all tasks finish — in roughly the time of the slowest operation.
Wrong
var result1 = await FetchDataAsync(1);
var result2 = await FetchDataAsync(2);
var result3 = await FetchDataAsync(3);
// Total time: sum of all three operations
Output: Works. Takes 3 seconds if each operation is 1 second.
Right
var task1 = FetchDataAsync(1);
var task2 = FetchDataAsync(2);
var task3 = FetchDataAsync(3);
var allResults = await Task.WhenAll(task1, task2, task3);
// Total time: ~1 second (the slowest operation)
Output: Same results. Takes ~1 second instead of 3. The tasks run in parallel.
Task.WhenAll also works with collections and handles faulted tasks:
var tasks = urls.Select(url => httpClient.GetStringAsync(url));
var pages = await Task.WhenAll(tasks);
// If any task faults, the aggregate exception contains all errors
Prevention
- Use
Task.WhenAllfor independent operations (no shared state). - Use
Task.WhenAllwith collections by projecting with LINQ. - Handle exceptions — wrap in
try-catchto collect all errors. - Use
Task.WhenAnywhen you need the first completed task. - Do not use
Task.WhenAllfor CPU-bound work — useParallel.ForEachorParallel LINQinstead. - Use
SemaphoreSlimfor throttling when you have too many concurrent tasks.
Common Mistakes with task when all
- Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
- Using
headandtailinstead of pattern matching, causing runtime errors on empty lists - Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
These mistakes appear frequently in real-world CSHARP code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Task.WhenAll is used in Doda Browser to fetch extension metadata in parallel. For more C# async, visit DodaTech.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro