Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Task.WhenAll in async method, then unwrapping each task [duplicate]

I have two tasks that can be run in parallel to increase performance:

var task1 = _service.DoStuffAsync();
var task2 = _service.DoOtherStuffAsync();

await Task.WhenAll(task1, task2);

Now, I'm sure that these tasks are done. But per my understanding (and some real life headaches), if I call .Result on these tasks, I could cause a deadlock, even though they are complete?

From what I was reading,awaiting a completed task simply returns the result, so it seems like that is the way to go here. That makes my code look funky:

var task1 = _service.DoStuffAsync();
var task2 = _service.DoOtherStuffAsync();

await Task.WhenAll(task1, task2);

var result1 = await task1;
var result2 = await task2;

Is this the correct way to solve this problem and get the results of both my tasks? If not, what's the problem? Is there a better way to unwrap the tasks without calling .Result on them?

like image 875
Jonesopolis Avatar asked Jan 26 '26 04:01

Jonesopolis


1 Answers

if I call .Result on these tasks, I could cause a deadlock, even though they are complete?

No, you can't. If the task is complete the Result will not block, it will immediately return, but more importantly you can't prevent the task that you're waiting on from finishing when it has already finished.

Is this the correct way to solve this problem and get the results of both my tasks?

It will certainly work. You are of course right that it looks silly, as you're redundantly awaiting the tasks twice (the second time won't actually take any time, as they're done, you're just typing out the code to wait for them twice). You can omit that redundant code, and simply await them the one time:

var task1 = _service.DoStuffAsync();
var task2 = _service.DoOtherStuffAsync();

var result1 = await task1;
var result2 = await task2;
like image 100
Servy Avatar answered Jan 28 '26 16:01

Servy