关于Task.Start(),Task.Run()和Task.Factory.StartNew()的使用

Mou*_*Mou 129 .net c# task-parallel-library async-await

我刚看到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();                  
}
Run Code Online (Sandbox Code Playgroud)

我只是不明白为什么MS给出了三种不同的方式在运行第三方物流工作,因为他们所有的工作一样的:Task.Start(),Task.Run()Task.Factory.StartNew().

告诉我,是Task.Start(),Task.Run()并且Task.Factory.StartNew()所有用于同一目的或者它们有不同的意义吗?

应该Task.Start()何时使用,何时应该使用Task.Run()何时使用Task.Factory.StartNew()

请帮助我通过示例非常详细地了解它们的实际用法,谢谢.

i3a*_*non 154

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

Task.Factory.StartNew(
    action, 
    CancellationToken.None, 
    TaskCreationOptions.DenyChildAttach, 
    TaskScheduler.Default);
Run Code Online (Sandbox Code Playgroud)

它被添加到.Net 4.5中,以帮助日益频繁地使用async和卸载工作ThreadPool.

Task.Factory.StartNew(在.Net 4.0中加入TPL)更加强大.如果Task.Run还不够,你应该只使用它,例如当你想要使用时TaskCreationOptions.LongRunning(尽管在委托是异步的时候是不必要的.在我的博客上有更多内容:LongRunning对于Task.Run使用async-await是无用的).更多关于Task.Factory.StartNewTask.Run VS Task.Factory.StartNew

除非你找到一个非常好的理由,否则不要创建Task和打电话Start().只有在某些部分需要创建任务而不是计划任务而另一部分计划而不创建时,才应该使用它.这几乎从来都不是一个合适的解决方案,而且可能很危险.更多内容见"Task.Factory.StartNew"vs"new Task(...).Start"

总之,主要是使用Task.Run,Task.Factory.StartNew如果你必须使用,永远不要使用Start.

  • 你说"不要创建一个任务并调用Start()"将我重定向到任何好的写入,这将显示可能由Task.Start()引起的.我需要细节,因为你说要避免它.谢谢你的答复. (5认同)
  • @Mou你应该阅读解释这个问题的帖子http://blogs.msdn.com/b/pfxteam/archive/2010/06/13/10024153.aspx (2认同)

Ali*_*yat 8

简短的回答

如果您没有使用嵌套的子任务并且总是希望您的任务在线程池上执行,那么最好使用Task.Run.

长答案:

Task.Run并且 Task.Factory.StartNew都提供了对创建和调度 Task 对象的支持,因此我们不需要创建Task和调用Start()

Task.Run(action);
Run Code Online (Sandbox Code Playgroud)

相当于:

Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
Run Code Online (Sandbox Code Playgroud)

Task.Factory.StartNew(action);
Run Code Online (Sandbox Code Playgroud)

相当于:

Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Current);
Run Code Online (Sandbox Code Playgroud)

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

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