I'm using an API client that is completely asynchrounous, that is, each operation either returns Task
or Task<T>
, e.g:
static async Task DoSomething(int siteId, int postId, IBlogClient client)
{
await client.DeletePost(siteId, postId); // call API client
Console.WriteLine("Deleted post {0}.", siteId);
}
Using the C# 5 async/await operators, what is the correct/most efficient way to start multiple tasks and wait for them all to complete:
int[] ids = new[] { 1, 2, 3, 4, 5 };
Parallel.ForEach(ids, i => DoSomething(1, i, blogClient).Wait());
or:
int[] ids = new[] { 1, 2, 3, 4, 5 };
Task.WaitAll(ids.Select(i => DoSomething(1, i, blogClient)).ToArray());
Since the API client is using HttpClient internally, I would expect this to issue 5 HTTP requests immediately, writing to the console as each one completes.
Best Answer
Although you run the operations in parallel with the above code, this code blocks each thread that each operation runs on. For example, if the network call takes 2 seconds, each thread hangs for 2 seconds w/o doing anything but waiting.
On the other hand, the above code with
WaitAll
also blocks the threads and your threads won't be free to process any other work till the operation ends.Recommended Approach
I would prefer
WhenAll
which will perform your operations asynchronously in Parallel.To back this up, here is a detailed blog post going through all the alternatives and their advantages/disadvantages: How and Where Concurrent Asynchronous I/O with ASP.NET Web API