返回Task <T>的方法是否总是启动返回的任务?

kar*_*l.r 11 c# task-parallel-library

如果我有一个像这样的方法

Task<bool> LongProcessTaskAsync();
Run Code Online (Sandbox Code Playgroud)

返回已启动的任务是否更好?

return Task<bool>.Factory.StartNew(() => { ... });
Run Code Online (Sandbox Code Playgroud)

要不就 return new Task<bool>(() => ...)

就个人而言,我更喜欢第一种方法,但我宁愿与其他API和库保持一致.

返回一个未启动的任务更合适吗?

Jam*_*ing 16

对于async/await方法,Task已经启动.AFAIK,为基于任务的版本添加的所有BCL方法都返回已启动的任务.因为普通的消费者案例现在是这样的,所以有点奇怪:

var foo = await GetFooAsync();
Run Code Online (Sandbox Code Playgroud)

[ 编辑 ]根据斯蒂芬指出TAP指南涵盖了这一点(他已经包含了指南的链接),我将在第4页中包含相关位的引用(在基于任务的异步模式中定义 - >行为 - >任务状态),我在关键部分周围添加了粗体+斜体.

任务状态

Task类为异步操作提供生命周期,该循环由TaskStatus枚举表示.为了支持从任务和任务派生的类型的极端情况以及构造与调度的分离,Task类公开了一个Start方法.由其公共构造函数创建的任务被称为"冷"任务,因为它们在非调度的TaskStatus.Created状态中开始其生命周期,并且直到在这些实例上调用Start才会进行调度.所有其他任务在"热"状态下开始其生命周期,这意味着它们所代表的异步操作已经启动,并且它们的TaskStatus是除Created之外的枚举值.

从TAP方法返回的所有任务必须"热". 如果TAP方法在内部使用Task的构造函数来实例化要返回的任务,则TAP方法必须在返回Task对象之前调用Start.TAP方法的消费者可以安全地假设返回的任务是"热门",并且不应该尝试在从TAP方法返回的任何任务上调用Start. 在"热"任务上调用Start将导致InvalidOperationException(此检查由Task类自动处理).

  • +1.[基于任务的异步模式指南](http://www.microsoft.com/en-us/download/details.aspx?id=19957)声明应该启动返回的`Task`.任何使用您的方法的`async`代码都会期望它被启动,特别是如果它遵循TAP命名准则(即以'Async`结尾). (2认同)
  • 非启动任务实际上仅由任务并行库代码使用。还有其他从 TPL 继承的 `Task` API 不应该在 TAP 代码中使用:`Task.Wait`、`Task.WaitAll`、`Task.WaitAny`、`Task.Result` - 本质上是任何处理阻塞的东西。 (2认同)
  • @Alisson:如果在方法的末尾,我将使用`await Task.WhenAll(myTask,myOtherTask).ConfigureAwait(false)`。 (2认同)