创build线程 – Task.Factory.StartNew vs new Thread()

我只是在.NET 4中学习新的线程和并行库

在过去,我会创build一个像这样的新线程(作为一个例子):

DataInThread = new Thread(new ThreadStart(ThreadProcedure)); DataInThread.IsBackground = true; DataInThread.Start(); 

现在我可以这样做:

 Task t = Task.Factory.StartNew(() => { ThreadProcedure(); }); 

有什么区别?

谢谢

有一个很大的不同。 任务安排在ThreadPool上,甚至可以在适当的时候同步执行。

如果您有长时间的后台工作,您应该使用正确的任务选项来指定。

您应该更喜欢任务并行库超过显式线程处理,因为它是更优化的。 你也有更多的function,如Continuation。

任务给你所有的任务API的好处:

  • 添加延续( Task.ContinueWith
  • 等待多个任务完成(全部或任何)
  • 捕获任务中的错误并在稍后进行询问
  • 捕获取消(并允许您指定取消开始)
  • 可能有一个返回值
  • 在C#5中使用await
  • 更好地控制调度(如果要长时间运行,在创build任务时这样说,以便任务调度程序可以考虑这一点)

请注意,在这两种情况下,使用方法组转换可以使代码稍微简单一些:

 DataInThread = new Thread(ThreadProcedure); // Or... Task t = Task.Factory.StartNew(ThreadProcedure); 

在第一种情况下,您只需启动一个新线程,而在第二种情况下,您将进入线程池。

线程池作业是共享和回收线程。 它可以避免每次我们需要创build一个新的线程时丢失几毫秒。

有几种方法可以进入线程池:

  • 与你一样的TPL (任务并行库)
  • 通过调用ThreadPool.QueueUserWorkItem
  • 通过调用委托上的BeginInvoke
  • 当您使用BackgroundWorker时

你的第一块代码告诉CLR为你创build一个可以作为后台运行的线程(比如T)(当调度T时使用线程池线程)。 简而言之,您明确地要求CLR创build一个线程,以便您可以执行某些操作,并在线程上调用Start()方法来启动。

你的第二块代码是一样的,但委托(隐式切换)创build线程(背景 – 再次在线程池中运行)的责任和启动线程通过任务工厂实施中的StartNew方法。

这是给定的代码块之间的快速差异。 话虽如此,你可以谷歌或看到其他贡献者的其他答案的细节差别很less。