任务.WhenAll和任务启动行为

14

我有一个使用Task.WhenAll的相当简单的应用程序。到目前为止,我面临的问题是我不知道是否应该自己启动子任务,还是让WhenAll根据需要启动它们。

在线示例展示了使用框架方法中的任务,我不清楚返回的任务是否已经启动。但是我使用了一个Action创建了自己的任务,所以这是一个我必须处理的细节。

当我使用Task.WhenAll时,我应该直接启动组成部分的任务,还是应该让Task.WhenAll处理它,以获得乐趣、利润和更好的执行速度?

此外,子任务包含大量阻塞I/O操作。


2
请发布一些代码以说明您如何构建任务。Task.WhenAll不会启动任务。通常的模式是返回Task的方法返回一个_hot_ Task。即已经在运行的任务。Task.Run就是这样工作的。 - Gusdor
1
Task.WhenAll 的目的不是启动或控制任务的执行顺序,而是提供一个聚合点;一个代表某些组成任务完成(及其结果集合)的任务。 - Asad Saeeduddin
3个回答

27

WhenAll 不会为您启动任务。您需要自己启动它们。

var unstartedTask = new Task(() => {});
await Task.WhenAll(unstartedTask); // this task won't complete until unstartedTask.Start()

然而,通常情况下,已创建的任务(例如使用 Task.Runasync 方法等)已经启动。因此,您通常不需要采取单独的操作来启动任务。

var task = Task.Run(() => {});
await Task.WhenAll(task); // no need for task.Start()

2
嘿兄弟。你解释得真好。赞一个。 - Reyan Chougle

5

我已经使用一个Action创建了自己的任务

当您使用异步任务时,惯例是只处理已经在进行中的任务。因此,使用Task构造函数和Start是不合适的;最好使用Task.Run

正如其他人所指出的,Task.WhenAll仅聚合任务;它不会为您启动它们。


1

Task.WhenAll(IEnumerable)会为您处理提供的任务,但您可以使用最常见的方式创建它们-通过执行Task.Run(Action)或TaskFactory.StartNew(Action)方法。

仅供参考:如果任何任务以故障状态完成,则结果任务也将以故障状态完成,并将其AggregateException设置为异常属性。


1
我相当确定这是不正确的。如果你将一个未启动的任务提供给WhenAll,结果任务将永远不会完成。 - Asad Saeeduddin
很抱歉,这取决于任务的初始状态。有许多创建任务的方法,其中一些会自动启动它。谢谢,我会更新我的答案。 - Ievgen Baida

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接