What are the main differences between the following conventions.
First:
Task myTask = new Task(()=>
{
// executable statements
});
myTask.Start();
Second:
Task.Run(()=>
{
// executable statements
});
Third:
Task.Factory.StartNew(() =>
{
// executable statements
});
Firstly, this information is avalible with a simple google.
A. From MSDN "Task.Factory.StartNew" vs "new Task(...).Start"
With TPL, there are several ways to create and start a new task. One way is to use the constructor for task followed by a call to the Start method, e.g.
new Task(...).Start();and the other is by using the StartNew method of
TaskFactory, e.g.Task.Factory.StartNew(...);This begs the question... when and why would you use one approach versus the other?
In general, I always recommend using
Task.Factory.StartNewunless the particular situation provides a compelling reason to use the constructor followed by Start. There are a few reasons I recommend this. For one, it's generally more efficient. For example, we take a lot of care within TPL to make sure that when accessing tasks from multiple threads concurrently, the "right" thing happens. ATaskis only ever executed once, and that means we need to ensure that multiple calls to a task's Start method from multiple threads concurrently will only result in the task being scheduled once. This requires synchronization, and synchronization has a cost. If you construct a task using the task's constructor, you then pay this synchronization cost when calling theStartmethod, because we need to protect against the chance that another thread is concurrently calling Start. However, if you useTask.Factory.StartNew, we know that the task will have already been scheduled by the time we hand the task reference back to your code, which means it's no longer possible for threads to race to call Start, because every call toStartwill fail. As such, forStartNewwe can avoid that additional synchronization cost and take a faster path for scheduling the task.
B. From MSDN Task.Run vs Task.Factory.StartNew
So, in the .NET Framework 4.5 Developer Preview, we’ve introduced the new
Task.Runmethod. This in no way obsoletesTask.Factory.StartNew, but rather should simply be thought of as a quick way to useTask.Factory.StartNewwithout needing to specify a bunch of parameters. It’s a shortcut. In fact,Task.Runis actually implemented in terms of the same logic used forTask.Factory.StartNew, just passing in some default parameters. When you pass anActiontoTask.Run:Task.Run(someAction);that’s exactly equivalent to:
Task.Factory.StartNew(someAction, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);In this way,
Task.Runcan and should be used for the most common cases of simply offloading some work to be processed on the ThreadPool (whatTaskScheduler.Defaulttargets). That doesn’t meanTask.Factory.StartNewwill never again be used; far from it.Task.Factory.StartNewstill has many important (albeit more advanced) uses. You get to controlTaskCreationOptionsfor how the task behaves. You get to control the scheduler for where the task should be queued to and run. You get to use overloads that accept object state, which for performance-sensitive code paths can be used to avoid closures and the corresponding allocations. For the simple cases, though,Task.Runis your friend.
I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With