我有一个使用Task.WhenAll的相当简单的应用程序。到目前为止,我面临的问题是我不知道是否应该自己启动子任务,还是让WhenAll根据需要启动它们。
在线示例展示了使用框架方法中的任务,我不清楚返回的任务是否已经启动。但是我使用了一个Action创建了自己的任务,所以这是一个我必须处理的细节。
当我使用Task.WhenAll时,我应该直接启动组成部分的任务,还是应该让Task.WhenAll处理它,以获得乐趣、利润和更好的执行速度?
此外,子任务包含大量阻塞I/O操作。
我有一个使用Task.WhenAll的相当简单的应用程序。到目前为止,我面临的问题是我不知道是否应该自己启动子任务,还是让WhenAll根据需要启动它们。
在线示例展示了使用框架方法中的任务,我不清楚返回的任务是否已经启动。但是我使用了一个Action创建了自己的任务,所以这是一个我必须处理的细节。
当我使用Task.WhenAll时,我应该直接启动组成部分的任务,还是应该让Task.WhenAll处理它,以获得乐趣、利润和更好的执行速度?
此外,子任务包含大量阻塞I/O操作。
WhenAll
不会为您启动任务。您需要自己启动它们。
var unstartedTask = new Task(() => {});
await Task.WhenAll(unstartedTask); // this task won't complete until unstartedTask.Start()
然而,通常情况下,已创建的任务(例如使用 Task.Run
、async
方法等)已经启动。因此,您通常不需要采取单独的操作来启动任务。
var task = Task.Run(() => {});
await Task.WhenAll(task); // no need for task.Start()
我已经使用一个Action创建了自己的任务
当您使用异步任务时,惯例是只处理已经在进行中的任务。因此,使用Task
构造函数和Start
是不合适的;最好使用Task.Run
。
正如其他人所指出的,Task.WhenAll
仅聚合任务;它不会为您启动它们。
Task.WhenAll(IEnumerable)会为您处理提供的任务,但您可以使用最常见的方式创建它们-通过执行Task.Run(Action)或TaskFactory.StartNew(Action)方法。
仅供参考:如果任何任务以故障状态完成,则结果任务也将以故障状态完成,并将其AggregateException设置为异常属性。
WhenAll
,结果任务将永远不会完成。 - Asad Saeeduddin
Task.WhenAll
不会启动任务。通常的模式是返回Task
的方法返回一个_hot_Task
。即已经在运行的任务。Task.Run
就是这样工作的。 - GusdorTask.WhenAll
的目的不是启动或控制任务的执行顺序,而是提供一个聚合点;一个代表某些组成任务完成(及其结果集合)的任务。 - Asad Saeeduddin