Task.Run中的默认TaskCreationOptions

时间:2013-05-11 16:50:22

标签: c# task-parallel-library threadpool async-await c#-5.0

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

与使用C#5.0中的新asyncawait更简单(通过阻止您逃避当前上下文的当前调度程序,我猜)有什么关系吗?

2 个答案:

答案 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“应该简单地被认为是一种使用Task.Factory.StartNew的快捷方式,而无需指定一堆参数。这是一个捷径”
  • Task.Run(someAction);完全等同于:

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

MSDN文章Nested Tasks and Child Tasks (for .NET 4.0,即没有任何与C#5.0 / .NET 4.5相同的内容)声明:

  

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

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