我在网上找到了一段代码,并稍微修改了一下来查看它的工作原理,但现在我遇到了一个问题,就是 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
中添加的所有结果写入控制台。
我已经使用了这段代码等待所有任务完成,但似乎它并没有等待它们,因为程序在启动后仅几毫秒就显示标准的 "按任意键继续"
消息。(应该需要 ~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
不会等待所有结果被计算完毕,而程序就像没有那行代码一样迅速结束(几毫秒后)吗?
ContinueWhenAll
时,程序不会在那一行“等待”,而是会继续执行下一行,并同时创建一个新的任务,该任务将不会执行,直到提供的任务完成。但是,WaitAll
会在那一行“阻塞”,直到所有提供的任务完成它们的执行。 - Jalal SaidContinueWhenAll
方法将安排一个新的任务,在第一组任务完成后运行。它不会在调用ContinueWhenAll
的线程中导致任何等待。当该博客说它等待任务数组完成时,它仅意味着新任务等待其他任务完成。有时候,您应该尝试阅读官方文档,它说:“创建一个继续任务,该任务将在提供的一组任务完成后启动”。而不是依赖博客。 - Ben Voigt