我在网上找到了一段代码并对其进行了一些修改以了解它是如何工作的,但现在我遇到了ContinueWhenAll
的问题,因为它不等待所有任务完成:
List<Task> tasks = new List<Task>();
for (int i = 0; i < 20; i++)
{
int j = i;
var compute = Task.Factory.StartNew(() => results.Add(DoSomething(j)));
tasks.Add(compute);
}
我正在使用此代码将所有任务添加到列表中。 DoSomething
函数会计算一些结果并将其添加到BlockingCollection
。我有另一个显示功能,它将BlockingCollection
的所有添加结果写入控制台。
我已经使用此代码等待所有任务完成,但看起来它不会等待它们,因为程序在启动后几毫秒内显示标准"Press any key to continue"
消息。 (程序完成需要约20秒)
Task.Factory.ContinueWhenAll(tasks.ToArray(), result => results.CompleteAdding());
但是,如果我将Task.WaitAll(consume)
添加到程序结尾,程序运行正常:
var consume = Task.Factory.StartNew(() => display(results));
//results = BlockingCollection that I mentioned
据我了解,该程序没有足够的时间显示BlockingCollection
的所有结果,但仍有足够的时间在等待所有任务完成时显示一些结果。
有人可以解释一下为什么Task.Factory.ContinueWhenAll不等待计算所有结果并且程序结束就像程序中没有那行代码(几毫秒之后)一样?
答案 0 :(得分:15)
Task.Factory.ContinueWhenAll
不是阻止方法;它实际上会启动一个只在所有提供的任务完成执行时才能运行的新任务。所以在程序启动后几毫秒看到一条消息是正常的,因为它不会阻止在你的主要等待任务完成。
来自msdn:
创建一个继续任务,该任务将在完成一组提供的任务后启动。
Task.WaitAll
阻止阻止在等待所有提供的任务完成执行的调用者。