8.17Parallel Requests (Batch Downloads)
In scenarios where multiple HTTP requests need to be sent simultaneously (such as batch downloads, concurrently calling multiple APIs, mixing the execution of different types of requests, etc.), you can use the framework's built-in ParallelUtility utility class, which provides a more concise API and supports controlling the maximum degree of concurrency.
Concurrently Executing the Same Operation on a Collection
Use ParallelUtility.ForEachAsync to concurrently execute the same asynchronous operation on each element of a collection:
var urls = new[]{ "https://furion.net/api/users", "https://furion.net/api/orders", "https://furion.net/api/products"};// Concurrent requests, default maximum degree of concurrency is 4var results = await ParallelUtility.ForEachAsync(urls, async (url, token) =>{ return await _httpRemoteService.GetAsStringAsync(url, cancellationToken: token);});// results are returned in the original collection orderYou can also control the maximum degree of concurrency via the maxDegreeOfParallelism parameter:
await ParallelUtility.ForEachAsync(urls, async (url, token) =>{ await _httpRemoteService.GetAsStringAsync(url, cancellationToken: token);}, maxDegreeOfParallelism: 2); // Execute at most 2 requests concurrentlyConcurrently Executing Multiple Different Operations
When you need to simultaneously execute multiple different types of operations, use ParallelUtility.RunAsync:
// Concurrently execute multiple different requests; all operations run simultaneouslyawait ParallelUtility.RunAsync( token => _httpRemoteService.GetAsStringAsync("https://furion.net/api/users", cancellationToken: token), token => _httpRemoteService.PostAsStringAsync("https://furion.net/api/orders", "\"Furion\"", cancellationToken: token), token => _httpRemoteService.DownloadFileWithConsoleProgressAsync("https://furion.net/logo.png", @"C:\Workspaces\", FileExistsBehavior.Overwrite, cancellationToken: token));If you need to obtain the return values, you can use the generic overload:
var results = await ParallelUtility.RunAsync( async token => await _httpRemoteService.GetAsStringAsync("https://furion.net/api/users", cancellationToken: token), async token => await _httpRemoteService.GetAsStringAsync("https://furion.net/api/orders", cancellationToken: token), async token => await _httpRemoteService.GetAsStringAsync("https://furion.net/api/products", cancellationToken: token));// results[0], results[1], results[2] correspond to the results of each operation in the order passed in