我有一个C#控制台应用程序,它会产生多个任务线程。在退出应用程序之前,我需要等待它们全部完成,否则它将关闭所有线程。如何在ConfiguredTaskAwaiter上执行“ .WaitAll()”(我假设这就是我要观看的内容)
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
答案 0 :(得分:1)
Configure await并不会更改任务本身的任何属性,它只是告诉编译器您在等待任务后是否在意当前上下文。因此
var task = Task.Delay(1000);
// ...
await task.ConfigureAwait(false);
与
相同var task = Task.Delay(1000).ConfigureAwait(false);
// ...
await task;
在您的特定情况下,为您实际上不打算等待的任务配置等待是没有意义的。您应该汇总它们,然后等待它们全部在一起。
您可能想做的是
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);
这告诉编译器,您不在乎等待后的上下文。由于您不等待单个任务,因此在等待这些上下文后再担心上下文是没有意义的。您将只等待代表所有任务的任务,即Task.WhenAll
返回的任务。
我也自由地将延续放在回调中。如果您出于某种原因不想这样做,请随意按照问题的方式进行拆分,该方法将以相同的方式工作。
答案 1 :(得分:0)
var taskList = new List<Task>();
foreach (var entityType in entityTypes)
{
....
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray())
,但是您应该然后使用名为 WhenAll 的异步版本:
await Task.WhenAll(taskList)