Task.Run中的默认TaskCreationOptions

Kav*_*ian 7 c# threadpool task-parallel-library async-await c#-5.0

为什么默认值CreationOptionsTask使用产生Task.RunDenyChildAttach,而不是None

它有什么关系使工作与新asyncawait在C#5.0简单(防止你逃跑当前上下文我猜的电流调度)?

Ste*_*ary 8

Stephen Toub 在他关于这个主题的博客文章中解释了这一点.

Task以并行方式使用s 时,父和子任务有些常见.请注意,当父项Task具有子项时,父项的完成语义会略有变化.

Task以某种async方式使用s 时,几乎从不使用父/子任务.在async世界上,当一个async方法调用另一个方法时,你有一种"逻辑父/子关系" ,但它实际上并没有使用父/子任务来实现.

通常Task,用于async代码的预期不会通过附加到其上的子任务来改变其完成语义.因此,Task.Runis 的新默认值DenyChildAttach会阻止任何尝试附加的子任务.


Gen*_*нин 5

为什么使用Task.Run创建的Task的CreationOptions的默认值是DenyChildAttach而不是None?

使用Task.Run方法创建任务时没有(默认或其他)选项.

引用Task.Run与Task.Factory.StartNew(作者Stephen Toub - MSFT):

  • Task.Run"应该简单地被认为是一种使用Task.Factory.StartNew的快捷方式,而无需指定一堆参数.这是一个捷径"
  • Task.Run(someAction); 完全等同于:

    Task.Factory.StartNew
        (   someAction
            , CancellationToken.None
            , TaskCreationOptions.DenyChildAttach
            , TaskScheduler.Default
         );  
    
    Run Code Online (Sandbox Code Playgroud)
  • "通过这种方式,Task.Run可以而且应该用于最常见的情况"

MSDN文章嵌套任务和子任务(对于.NET 4.0,即没有任何C#5.0/.NET 4.5的等价物)声明:

"在大多数情况下,我们建议您使用嵌套任务,因为与其他任务的关系不太复杂.这就是默认情况下嵌套在其他任务中创建的任务的原因,您必须显式指定AttachedToParent选项以创建子任务"

这解释了为什么CreationOptions.DenyChildAttach被选为快捷方式最常见和最简单的选项.