更新时间: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);