Task.Run and Task.Factory.StartNew

The Task.Run method was introduced in .NET 4.5 (back in 2012 I think) to simplify the cases where one needs to offload some work to the thread pool. Previously we used TaskFactory.StartNew method which has much more flexibility – and the inherent complexity. If not used correctly, the different parameter combinations could allow strange/bogus behaviors, such as accidentally starting a task on the UI thread.

Even though Task.Run simplifies the general case, from time to time I find myself wondering which is happening under the hood. Using some decompiler we can what Task.Run(Action action) is doing:

public static Task Run(Action action)
StackCrawlMark stackCrawlMark = StackCrawlMark.LookForMyCaller;
return Task.InternalStartNew(null, action, null,
InternalTaskOptions.None, ref stackCrawlMark);

So, it’s using:

  • TaskScheduler.Default – This ensures we’re offloading to the thread pool. One of the problems of not specifying the scheduler when using Task.Factory.StartNew is that it uses TaskScheduler.Current, which might be other than the default. In .NET 4.5 there’s also the TaskCreationOptions.HideScheduler flag, which results in TaskScheduler.Current being TaskScheduler.Default within the created task, even if it runs on a different scheduler
  • TaskCreationOptions.DenyChildAttach – This ensures that tasks created within the current task that specify TaskCreationOptions.AttachToParent won’t actually attach to anything because they won’t “see” the current task.

It’s worth pointing that the Task.Run call above is equivalent to:

Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

Both these arguments make sense as defaults and they are specially important when invoking external code. .NET folks actually admit they would make it the default if they could redo .NET 4.

You can find this and other useful information on the pfxteam blog; I really recommend reading it!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s