Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running multiple async tasks and waiting for them all to complete

I need to run multiple async tasks in a console application, and wait for them all to complete before further processing.

There's many articles out there, but I seem to get more confused the more I read. I've read and understand the basic principles of the Task library, but I'm clearly missing a link somewhere.

I understand that it's possible to chain tasks so that they start after another completes (which is pretty much the scenario for all the articles I've read), but I want all my Tasks running at the same time, and I want to know once they're all completed.

What's the simplest implementation for a scenario like this?

like image 919
Daniel Minnaar Avatar asked Jul 29 '14 06:07

Daniel Minnaar


People also ask

Can one async function have multiple awaits?

In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() . Promise. all() will wait for all the provided async calls to be resolved before it carries on(see Conclusion for caveat).

How do you wait for multiple tasks?

The correct way to await multiple tasks is the Task. WhenAll method: await Task. WhenAll(first, second); . Then you can await them individually to get their results, because you know that all have completed successfully.

Does parallel invoke wait for completion?

Now, the Parallel. Invoke does not wait for the methods to finish and the spinner is instantly off.

Which of the below statement creates a task that will complete when all of the supplied tasks have completed?

WhenAll(IEnumerable<Task>) Creates a task that will complete when all of the Task objects in an enumerable collection have completed.


1 Answers

Both answers didn't mention the awaitable Task.WhenAll:

var task1 = DoWorkAsync(); var task2 = DoMoreWorkAsync();  await Task.WhenAll(task1, task2); 

The main difference between Task.WaitAll and Task.WhenAll is that the former will block (similar to using Wait on a single task) while the latter will not and can be awaited, yielding control back to the caller until all tasks finish.

More so, exception handling differs:

Task.WaitAll:

At least one of the Task instances was canceled -or- an exception was thrown during the execution of at least one of the Task instances. If a task was canceled, the AggregateException contains an OperationCanceledException in its InnerExceptions collection.

Task.WhenAll:

If any of the supplied tasks completes in a faulted state, the returned task will also complete in a Faulted state, where its exceptions will contain the aggregation of the set of unwrapped exceptions from each of the supplied tasks.

If none of the supplied tasks faulted but at least one of them was canceled, the returned task will end in the Canceled state.

If none of the tasks faulted and none of the tasks were canceled, the resulting task will end in the RanToCompletion state. If the supplied array/enumerable contains no tasks, the returned task will immediately transition to a RanToCompletion state before it's returned to the caller.

like image 112
Yuval Itzchakov Avatar answered Oct 25 '22 15:10

Yuval Itzchakov