【问题标题】:Task.WhenAll and task starting behaviourTask.WhenAll 和任务启动行为
【发布时间】:2015-10-29 09:03:45
【问题描述】:

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

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

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

为了更有趣,子任务包含大量阻塞 I/O。

【问题讨论】:

  • 请发布一些代码来说明您是如何构建任务的。 Task.WhenAll 不启动任务。一般模式是返回 Task 的方法,返回 hot Task。 IE。一个已经在运行的。 Task.Run 是这样工作的。
  • Task.WhenAll的重点不是启动或控制任务的执行顺序。它是提供一个聚合点;表示完成某些组成任务(及其结果的集合)的任务。

标签: c# task-parallel-library task


【解决方案1】:

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】:

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

当您处理异步任务时,the convention is to only deal with tasks already in progress。所以使用Task构造函数和Start是不合适的;最好使用Task.Run

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

【讨论】:

    【解决方案3】:

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

    请注意:如果任何任务在 Faulted 状态下完成,则生成的任务也将在 Faulted 状态下完成,并将 AggregateException 设置为其异常属性。

    【讨论】:

    • 我很确定这是不正确的。如果您向WhenAll 提供未开始的任务,则生成的任务将永远无法完成。
    • 不好,这取决于任务的初始状态。有很多方法可以创建任务,其中一些会自动启动它。谢谢,我会更新我的答案。
    猜你喜欢
    • 2018-02-03
    • 2015-02-02
    • 2022-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-30
    • 2012-11-06
    • 1970-01-01
    相关资源
    最近更新 更多