ContinueWhenAll 不等待所有任务完成

问题描述 投票:0回答:2

我在网上找到了一段代码并对其进行了一些修改以查看其工作原理,但是现在我遇到了问题

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 不等待计算所有结果并且程序结束就像程序中没有那行代码一样(几毫秒后)?

c# parallel-processing task
2个回答
18
投票

Task.Factory.ContinueWhenAll
不是阻塞方法;它实际上会启动一个新任务,只有当所有提供的任务都在那里执行完成时才会起作用,所以在程序启动后几毫秒看到一条消息是正常的,因为它不会 block 在你的主要等待要完成的任务。 来自 msdn:

创建将在完成一组提供的任务后启动的延续任务。

Task.WaitAll
block 在调用者处等待所有提供的任务完成执行。


0
投票

基于官方文档:

ContinueWhenAll
方法:

Creates a continuation task that starts when a set of specified tasks has completed.

所以它实际上是在创建一个新的Task,这不是阻塞操作。

© www.soinside.com 2019 - 2024. All rights reserved.