Task combinators
Task.WhenAll
Task.WhenAll awaits the completion of multiple tasks concurrently. It returns a single Task that completes when all the input tasks have completed. It’s useful for running several independent asynchronous operations in parallel, then processing their results together. For many I/O-bound operations at once, this is the tool, not Parallel.For: see how many jobs Parallel.For can runHow many jobs can Parallel.For run?No limit on how many you submit, a real limit on how many run at once.Opens in a new tab.
Line 3 starts one download per URL. Line 4 awaits all of them at once. Line 6 goes through the results.
// public async Task ProcessMultipleUrlsAsync(IEnumerable<string> urls)// {// var downloadTasks = urls.Select(url => DownloadWebContentAsync(url)).ToList();// string[] contents = await Task.WhenAll(downloadTasks);// // Process all downloaded contents// foreach (var content in contents) { /*... */ }// }Task.WhenAny
Task.WhenAny awaits the first task in a collection to finish. It returns a Task<Task>, where the inner task is the one that completed. It’s useful for implementing timeouts, or for using the result of the fastest of several redundant operations.
Sources
- C# Async/Await Explained: Complete Guide with Examples, NDepend Blog · accessed May 16, 2025