0

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.

18
  • 3
    Parallel.Foreach only 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. Commented Dec 19, 2019 at 15:45
  • Is your goal to execute Do1() in parallel? Commented Dec 19, 2019 at 15:48
  • 2
    because you didn't it to wait ... he did wrote it already nothing waits for that async void delegate Commented Dec 19, 2019 at 15:52
  • 1
    @ShakHam you're using the wrong class. Parallel.ForEach is 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 a Func<T,Task>. Your calls are essentially async void calls that nobody awaits Commented Dec 19, 2019 at 16:00
  • 1
    I was typing up an answer to clarify why Do2 works differently, but the question got closed. The short answer is that it's not doing anything asynchronous. If await sees a completed Task, then execution continues synchronously. And your Multiply method always returns a completed Task. Commented Dec 19, 2019 at 16:10

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.