为什么使用CreationOptions
创建的Task
Task.Run
的默认值为DenyChildAttach
而不是None
?
与使用C#5.0中的新async
和await
更简单(通过阻止您逃避当前上下文的当前调度程序,我猜)有什么关系吗?
答案 0 :(得分:8)
Stephen Toub很好地解释了这一点in his blog post on the subject。
以并行方式使用Task
时, Parent and child tasks有些常见。请注意,当父Task
有子节点时,父节点的完成语义会略有变化。
以Task
方式使用async
时几乎不会使用父/子任务。在async
世界中,当一个async
方法调用另一个Task
方法时,您有一种“逻辑父/子关系”,但它实际上并未使用父/子任务实现。
通常用于async
代码的Task.Run
通常不会通过附加到其上的子任务更改其完成语义。因此,DenyChildAttach
的新默认值为{{1}},可防止任何子任务尝试附加。
答案 1 :(得分:5)
为什么使用创建的Task的CreationOptions的默认值 Task.Run是DenyChildAttach而不是None?
使用Task.Run Method创建任务时没有(默认或其他)选项。
引自Task.Run vs Task.Factory.StartNew (by Stephen Toub - MSFT):
Task.Run(someAction);
完全等同于:
Task.Factory.StartNew
( someAction
, CancellationToken.None
, TaskCreationOptions.DenyChildAttach
, TaskScheduler.Default
);
MSDN文章Nested Tasks and Child Tasks (for .NET 4.0,即没有任何与C#5.0 / .NET 4.5相同的内容)声明:
“在大多数情况下,我们建议您使用嵌套任务,因为 与其他任务的关系不那么复杂。这就是为什么任务 默认情况下,嵌入在其他任务中创建的内容,您必须 显式指定AttachedToParent选项以创建子任务“
解释了为什么CreationOptions.DenyChildAttach
被选为快捷方式最常见和最简单的选项。