Reputation: 110650
I have the following code which calls 2 async methods and wait for results:
private Task FirstTaskAsync() {
...
}
private Task SecondTaskAsync() {
...
}
private async void Caller() {
await FirstTaskAsync();
await SecondTaskAsync();
}
Problem is it now executes and waits for each task sequentially. I want to change it to Task.WaitAll(). Here is my change:
private async void Caller() {
var first = FirstTaskAsync();
var second = SecondTaskAsync();
Task.WaitAll(first, second);
}
But when I test it, Task.WaitAll() never returns. Can you please tell me what is missing?
Upvotes: 0
Views: 1070
Reputation: 127603
First of all, you should never do async void
unless you are doing a event handler (which I doubt you are), if you did async Task
it makes it more obvious what your problem is.
private async Task Caller() {
await FirstTaskAsync();
await SecondTaskAsync();
}
//This still will not work...
private async Task Caller() {
var first = FirstTaskAsync();
var second = SecondTaskAsync();
Task.WaitAll(first, second);
}
Task.WaitAll
returns void and you never use await
in the second method, so you are executing the code synchronously and blocking on the SynchronizationContext
which will cause you to get deadlocks like you are seeing.
The correct solution would be not to block but instead use Task.WhenAll
which returns a Task itself which allows you to drop the async keyword and just return the result
private Task Caller() {
var first = FirstTaskAsync();
var second = SecondTaskAsync();
return Task.WhenAll(first, second);
}
However, if Caller()
really is a event handler you can also do async void
and just await the result.
private async void Caller() { //This should only be done if this is a event handler.
var first = FirstTaskAsync();
var second = SecondTaskAsync();
await Task.WhenAll(first, second);
}
Upvotes: 5
Reputation: 2522
Would this work for you?
private async void Caller()
{
Task[] tasks = new Task[2];
tasks[0] = FirstTaskAsync();
tasks[1] = SecondTaskAsync();
await Task.WhenAll(tasks);
}
Upvotes: 0