In the code below (a fairly simple one just for demonstration), my finally clause gets executed when awaiting for the HttpClient to finish. So the output is something like:
Done
StatusCode: 200,...
When I was expecting it to be:
StatusCode: 200,...
Done
class Program { private static HttpClient _httpClient = new HttpClient(); static async Task Main(string[] args) { var numbers = new List<int> {1}; try { await Task.Run(() => { Parallel.ForEach(numbers, async (number) => { await Do1(); }); }); } finally { Console.WriteLine("Done"); } Console.ReadKey(); } private static async Task Do1() { using (var result = await _httpClient.GetAsync("http://www.google.com")) { Console.WriteLine(result); } } private static async Task Do2() { for (int i = 0; i <= 10; i++) { Console.WriteLine("Doing" + await Multiply(i)); } } private static async Task<int> Multiply(int number) { return await Task.FromResult(number * number); } } If I replace my Main method to use the Do2 method then everything works as expected with the following output ("Done" gets printed at the very end):
.
.
.
Doing100
Done
So why is the HttpClient not working as I am expecting it to work? Something that I'd like to mention is that I would like to use the Parallel.ForEach instead of the Task.WhenAll function.
Parallel.Foreachonly accepts an action, which means when you give it async delegate you end up with an unawaitable async void and nothing waits for that async void delegate to complete before moving on.Parallel.ForEachis meant for data parallelism, not concurrent calls. It doesn't support asynchronous methods precisely because it's not meant for concurrent/asynchronous work. It has no overloads that accept aFunc<T,Task>. Your calls are essentiallyasync voidcalls that nobody awaitsDo2works differently, but the question got closed. The short answer is that it's not doing anything asynchronous. Ifawaitsees a completedTask, then execution continues synchronously. And yourMultiplymethod always returns a completedTask.