关于 Task.Start ()、 Task.Run ()和 Task.Factory. StartNew ()的用法

我刚才看到了3个关于 TPL 使用的例程,它们做着同样的工作; 下面是代码:

public static void Main()
{
Thread.CurrentThread.Name = "Main";


// Create a task and supply a user delegate by using a lambda expression.
Task taskA = new Task( () => Console.WriteLine("Hello from taskA."));
// Start the task.
taskA.Start();


// Output a message from the calling thread.
Console.WriteLine("Hello from thread '{0}'.",
Thread.CurrentThread.Name);
taskA.Wait();
}


public static void Main()
{
Thread.CurrentThread.Name = "Main";


// Define and run the task.
Task taskA = Task.Run( () => Console.WriteLine("Hello from taskA."));


// Output a message from the calling thread.
Console.WriteLine("Hello from thread '{0}'.",
Thread.CurrentThread.Name);
taskA.Wait();
}


public static void Main()
{
Thread.CurrentThread.Name = "Main";


// Better: Create and start the task in one operation.
Task taskA = Task.Factory.StartNew(() => Console.WriteLine("Hello from taskA."));


// Output a message from the calling thread.
Console.WriteLine("Hello from thread '{0}'.",
Thread.CurrentThread.Name);


taskA.Wait();
}

我只是不明白为什么 MS 给出了3种不同的方式来运行 TPL 作业,因为他们都工作相同: Task.Start()Task.Run()Task.Factory.StartNew()

告诉我,Task.Start()Task.Run()Task.Factory.StartNew()是用于同一个目的,还是它们有不同的意义?

什么时候应该使用 Task.Start(),什么时候应该使用 Task.Run(),什么时候应该使用 Task.Factory.StartNew()

请帮助我了解他们的真正用途,每个场景在很大的细节与例子,谢谢。

88001 次浏览

Task.RunTask.Factory.StartNew的简写,带有特定的安全参数:

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

是加进去的。净4.5,以帮助日益频繁的使用 async和卸载工作到 ThreadPool

Task.Factory.StartNew(在。净值4.0)则稳健得多。只有在 Task.Run不够的情况下才应该使用它,例如当您想要使用 TaskCreationOptions.LongRunning时(尽管在委托是异步的情况下没有必要使用它)。更多详情请看我的博客: 长时间运行对于任务没有用处。使用异步运行-等待)。更多关于 任务。运行对任务。工厂。开始新建Task.Factory.StartNew的资料

不要创建一个 Task并调用 Start(),除非你找到一个非常好的理由这样做。只有当您有需要创建任务但不安排任务的部分,以及另一个不安排任务但不创建任务的部分时,才应该使用该方法。这几乎从来都不是一个合适的解决方案,而且可能是危险的。更多在 “ Task.Factory. StartNew”vs“ new Task (...) . Start”

总之,大多数情况下使用的是 Task.Run,如果必须使用 Task.Factory.StartNew,就不要使用 Start

简短的回答 :

如果您不使用 嵌套式儿童任务,并且总是希望在 线程池上执行任务,那么最好使用 Task.Run

长话短说:

Task.RunTask.Factory.StartNew都支持创建和调度 Task 对象,所以我们不需要创建 Task并调用 Start()

Task.Run(action);

相当于:

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

还有

Task.Factory.StartNew(action);

相当于:

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

Task.Run使用 TaskCreationOptions.DenyChildAttach,这意味着子任务不能附加到父任务,它使用 TaskScheduler.Default,这意味着在线程池上运行任务的任务将始终用于运行任务。

Task.Factory.StartNew使用 TaskScheduler.Current,这意味着当前线程的调度程序,它可能是 TaskScheduler.Default,但不总是。