以下约定之间的主要区别是什么。
第一的:
Task myTask = new Task(()=>
{
// executable statements
});
myTask.Start();
第二:
Task.Run(()=>
{
// executable statements
});
第三:
Task.Factory.StartNew(() =>
{
// executable statements
});
以下约定之间的主要区别是什么。
第一的:
Task myTask = new Task(()=>
{
// executable statements
});
myTask.Start();
第二:
Task.Run(()=>
{
// executable statements
});
第三:
Task.Factory.StartNew(() =>
{
// executable statements
});
首先,此信息可通过简单的 google 获得。
A. 从 MSDN "Task.Factory.StartNew" 与 "new Task(...).Start"
使用 TPL,有多种方法可以创建和启动新任务。一种方法是使用 task 的构造函数,然后调用 Start 方法,例如
new Task(...).Start();
另一种是使用 StartNew 方法
TaskFactory
,例如Task.Factory.StartNew(...);
这就引出了一个问题……您何时以及为什么要使用一种方法而不是另一种方法?
一般来说,我总是建议使用
Task.Factory.StartNew
,除非特定情况提供了使用构造函数后跟 Start 的令人信服的理由。我推荐这个有几个原因。一方面,它通常更有效。例如,我们在 TPL 中非常小心,以确保当从多个线程同时访问任务时,会发生“正确”的事情。ATask
只执行一次,这意味着我们需要确保从多个线程同时多次调用任务的 Start 方法只会导致任务被调度一次。这需要同步,而同步是有代价的。如果使用任务的构造函数构造任务,则在调用Start
方法,因为我们需要防止另一个线程同时调用 Start。但是,如果您使用Task.Factory.StartNew
,我们知道在我们将任务引用交还给您的代码时,该任务已经安排好了,这意味着线程不再可能竞相调用 Start,因为每次调用Start
都会失败。因此,StartNew
我们可以避免额外的同步成本,并采用更快的路径来调度任务。
B. 从MSDN Task.Run 与 Task.Factory.StartNew
因此,在 .NET Framework 4.5 开发者预览版中,我们引入了新
Task.Run
方法。这绝不会过时Task.Factory.StartNew
,而是应该简单地认为是一种Task.Factory.StartNew
无需指定一堆参数的快速使用方式。这是一条捷径。实际上,Task.Run
实际上是按照与 for 相同的逻辑来实现的Task.Factory.StartNew
,只是传入了一些默认参数。当你传递一个Action
toTask.Run
:Task.Run(someAction);
这完全等同于:
Task.Factory.StartNew(someAction, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
通过这种方式,
Task.Run
可以并且应该用于最常见的情况,即简单地卸载一些要在 ThreadPool 上处理的工作(什么TaskScheduler.Default
目标)。这并不意味着Task.Factory.StartNew
永远不会再被使用;离得很远。Task.Factory.StartNew
仍然有许多重要(尽管更高级)的用途。您可以控制TaskCreationOptions
任务的行为方式。您可以控制任务应该在哪里排队和运行的调度程序。您可以使用接受对象状态的重载,这对于性能敏感的代码路径可用于避免闭包和相应的分配。但是,对于简单的情况,Task.Run
是您的朋友。
我希望这有帮助。