Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default TaskCreationOptions in Task.Run

Why the default value for CreationOptions of a Task created using Task.Run is DenyChildAttach rather than None?

Has it anything to do with making work with the new async and await in C# 5.0 simpler (by preventing you from escaping current scheduler of current context I guess)?

like image 621
Kaveh Shahbazian Avatar asked May 11 '13 16:05

Kaveh Shahbazian


People also ask

Does Task run use new thread?

NET code does not mean there are separate new threads involved. Generally when using Task. Run() or similar constructs, a task runs on a separate thread (mostly a managed thread-pool one), managed by the . NET CLR.

What is the difference between Task run () and Taskfactory StartNew () methods?

Task. Run(action) internally uses the default TaskScheduler , which means it always offloads a task to the thread pool. StartNew(action) , on the other hand, uses the scheduler of the current thread which may not use thread pool at all!

What is Task factory StartNew?

StartNew(Action, CancellationToken) Creates and starts a task for the specified action delegate and cancellation token. StartNew(Action, TaskCreationOptions) Creates and starts a task for the specified action delegate and creation options.

What does Task run do C#?

The Run method allows you to create and execute a task in a single method call and is a simpler alternative to the StartNew method. It creates a task with the following default values: Its cancellation token is CancellationToken.


2 Answers

Why the default value for CreationOptions of a Task created using Task.Run is DenyChildAttach rather than None?

There is no (default or other) options in creating a task using Task.Run Method.

Citing from Task.Run vs Task.Factory.StartNew (by Stephen Toub - MSFT):

  • Task.Run "should simply be thought of as a quick way to use Task.Factory.StartNew without needing to specify a bunch of parameters. It’s a shortcut"
  • Task.Run(someAction); is exactly equivalent to:

    Task.Factory.StartNew
        (   someAction
            , CancellationToken.None
            , TaskCreationOptions.DenyChildAttach
            , TaskScheduler.Default
         );  
    
  • "In this way, Task.Run can and should be used for the most common cases"

MSDN article Nested Tasks and Child Tasks (for .NET 4.0, i.e. without any equivokes for C# 5.0/.NET 4.5) states:

"in most scenarios, we recommend that you use nested tasks because the relationships with other tasks are less complex. That is why tasks created inside other tasks are nested by default, and you must explicitly specify the AttachedToParent option to create a child task"

which explains why CreationOptions.DenyChildAttach was chosen for the shortcut's most common and simplest option.

like image 81

Stephen Toub explains this well in his blog post on the subject.

Parent and child tasks are somewhat common when using Tasks in a parallel fashion. Note that when a parent Task has a child, the parent's completion semantics change subtly.

Parent/child tasks are almost never used when using Tasks in an async fashion. In the async world, you have a sort of "logical parent/child relationship" when one async method calls another, but it is not actually implemented using parent/child tasks.

Usually a Task intended for use in async code is not expecting to have its completion semantics changed by a child task attaching to it. Thus, the new default for Task.Run is DenyChildAttach, which prevents any child tasks attempting to attach.

like image 31
Stephen Cleary Avatar answered Oct 01 '22 07:10

Stephen Cleary