Problem
In a console application, I need to start numerous async jobs and wait for them all to finish before proceeding.
There are numerous articles available, but the more I read, the more perplexed I become. I’ve studied and comprehended the Task library’s essential principles, yet there’s plainly something lacking.
I realize that tasks can be chained such that one starts after the other (which is pretty much the situation in all of the articles I’ve read), but I want all of my Tasks to run at the same time, and I want to know when they’re all done.
What is the simplest way to implement this scenario?
Asked by Daniel Minnaar
Solution #1
Both answers failed to mention the pending Task. WhenAll:
var task1 = DoWorkAsync();
var task2 = DoMoreWorkAsync();
await Task.WhenAll(task1, task2);
The key distinction between Task and Task. Task and WaitAll The difference between When and WhenAll is that the former will block (equivalent to using Wait on a single job), whereas the latter will not and can be awaited, returning control to the caller once all tasks have completed.
Exception handling is also different:
Task.WaitAll:
Task.WhenAll:
Answered by Yuval Itzchakov
Solution #2
You could create many tasks like:
List<Task> TaskList = new List<Task>();
foreach(...)
{
var LastTask = new Task(SomeFunction);
LastTask.Start();
TaskList.Add(LastTask);
}
Task.WaitAll(TaskList.ToArray());
Answered by Virus
Solution #3
WhenAll returns an awaitable Task, while WaitAll has no return type and blocks further function execution in the same way that Thread does. Sleep until you’ve completed, canceled, or faulted all of your tasks.
Example
var tasks = new Task[] {
TaskOperationOne(),
TaskOperationTwo()
};
Task.WaitAll(tasks);
// or
await Task.WhenAll(tasks);
You can use this response for inspiration if you want to execute the jobs in a specific order.
Answered by NtFreX
Solution #4
The following extension method is the best solution I’ve seen:
public static Task ForEachAsync<T>(this IEnumerable<T> sequence, Func<T, Task> action) {
return Task.WhenAll(sequence.Select(action));
}
It’s referred to as:
await sequence.ForEachAsync(item => item.SomethingAsync(blah));
Alternatively, use an async lambda:
await sequence.ForEachAsync(async item => {
var more = await GetMoreAsync(item);
await more.FrobbleAsync();
});
Answered by me22
Solution #5
Another answer…but I generally find myself in a situation where I need to load data at the same time and store it in variables, such as:
var cats = new List<Cat>();
var dog = new Dog();
var loadDataTasks = new Task[]
{
Task.Run(async () => cats = await LoadCatsAsync()),
Task.Run(async () => dog = await LoadDogAsync())
};
try
{
await Task.WhenAll(loadDataTasks);
}
catch (Exception ex)
{
// handle exception
}
Answered by Yehor Hromadskyi
Post is based on https://stackoverflow.com/questions/25009437/running-multiple-async-tasks-and-waiting-for-them-all-to-complete