Reputation: 21
I have a C# console app that spawns multiple task threads. I need to wait for all of them to finish before exiting the app otherwise it closes all the threads. How can I do a ".WaitAll()" on the ConfiguredTaskAwaiter (I'm assuming that's what I want to watch)
foreach (var entityType in entityTypes)
{
// Create a task for each entity to thread the calls
var task = Task.Run(() => TestTaskAsync(entityType)).ConfigureAwait(false); // Long running process
var awaiter = task.GetAwaiter();
Action showComplete = () => OnComplete($"PROCESSING FOR ENTITY ({entityType.Id}) HAS COMPLETED.");
awaiter.OnCompleted(showComplete);
}
// Should not continue until all tasks have completed
Upvotes: 0
Views: 884
Reputation: 770
Configure await does not change any property of the task itself, it just tells the compiler whether you care about your current context after you await the task. Therefore
var task = Task.Delay(1000);
// ...
await task.ConfigureAwait(false);
is identical to
var task = Task.Delay(1000).ConfigureAwait(false);
// ...
await task;
In your specific case, it makes no sense to configure await for tasks you're not actually planning to await. You should aggregate them and await them all together instead.
What you probably want to do is
var tasks = new List<Task>();
foreach (var type in types)
{
var task = Task.Run(() =>
{
TestTaskAsync(entityType);
OnComplete($"PROCESSING FOR ENTITY ({entityType.Id}) HAS COMPLETED.");
});
tasks.Add(task);
}
await Task.WhenAll(tasks).ConfigureAwait(false);
This tells the compiler that you do not care what context you will have after the await. Since you are not awaiting the individual tasks, it makes no sense to worry about context after awaiting those. You will only be awaiting a task that represents them all, that is the task returned by Task.WhenAll
.
I also took the liberty of putting the continuation in the callback. If you do not want to do that for any reason, feel free to split it the way you have in your question, it will work the same way.
Upvotes: 4
Reputation: 1737
var taskList = new List<Task>();
foreach (var entityType in entityTypes)
{
....
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray())
but you should then async version called WhenAll :
await Task.WhenAll(taskList)
Upvotes: 0