且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Task.Run()和Task.Factory.StartNew()有什么区别

更新时间:2023-01-15 20:30:19

第二种方法Task.Run已在.NET Framework的更高版本中(在.NET 4.5中)引入.

The second method, Task.Run, has been introduced in a later version of the .NET framework (in .NET 4.5).

但是,第一种方法Task.Factory.StartNew使您有机会为要创建的线程定义很多有用的东西,而Task.Run没有提供此功能.

However, the first method, Task.Factory.StartNew, gives you the opportunity to define a lot of useful things about the thread you want to create, while Task.Run doesn't provide this.

例如,假设您要创建一个长时间运行的任务线程.如果线程池中的一个线程将用于此任务,则可以认为这是对线程池的滥用.

For instance, lets say that you want to create a long running task thread. If a thread of the thread pool is going to be used for this task, then this could be considered an abuse of the thread pool.

为避免这种情况,您可以做的一件事是在单独的线程中运行任务.一个新创建的线程专用于此任务,一旦完成任务便会被销毁. 无法通过Task.Run来实现,而您可以使用Task.Factory.StartNew进行操作,如下所示:

One thing you could do in order to avoid this would be to run the task in a separate thread. A newly created thread that would be dedicated to this task and would be destroyed once your task would have been completed. You cannot achieve this with the Task.Run, while you can do so with the Task.Factory.StartNew, like below:

Task.Factory.StartNew(..., TaskCreationOptions.LongRunning);

此处所述:

因此,在.NET Framework 4.5开发人员预览版中,我们引入了 新的Task.Run方法. 这绝不会过时,Task.Factory.StartNew, 但是应该简单地将其视为一种快捷的使用方式 Task.Factory.StartNew 无需指定一堆 参数.这是一个快捷方式.实际上,Task.Run实际上是 以与Task.Factory.StartNew相同的逻辑实现 只是传入一些默认参数.当您将动作传递给 Task.Run:

So, in the .NET Framework 4.5 Developer Preview, we’ve introduced the new Task.Run method. This in no way obsoletes Task.Factory.StartNew, but rather 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. In fact, Task.Run is actually implemented in terms of the same logic used for Task.Factory.StartNew, just passing in some default parameters. When you pass an Action to Task.Run:

Task.Run(someAction);

这完全等同于:

that’s exactly equivalent to:

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