创建线程 - Task.Factory.StartNew vs new Thread()

时间:2011-10-25 13:09:32

标签: c# .net multithreading .net-4.0

我刚学习.Net 4中新的线程和并行库

过去我会像这样创建一个新线程(例如):

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

现在我能做到:

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

有什么区别?

由于

4 个答案:

答案 0 :(得分:77)

有很大的不同。任务在ThreadPool上安排,如果合适,甚至可以同步执行。

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

您应该更喜欢任务并行库而不是显式线程处理,因为它更加优化。此外,您还有更多功能,例如Continuation。

答案 1 :(得分:72)

该任务为您提供了任务API的所有优点:

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

请注意,在这两种情况下,您都可以通过方法组转换使代码更简单:

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

答案 2 :(得分:12)

在第一种情况下,您只是开始一个新线程,而在第二种情况下,您正在进入线程池。

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

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

  • TPL (任务并行库)一样
  • 通过调用 ThreadPool.QueueUserWorkItem
  • 通过在代理
  • 上调用 BeginInvoke
  • 使用 BackgroundWorker

答案 3 :(得分:0)

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

您的第二个代码块执行相同操作,但委派(隐式切换)创建线程(后台 - 再次在线程池中运行)和启动线程通过Task Factory实现中的StartNew方法的责任。

这是给定代码块之间的快速差异。话虽如此,您可以谷歌或从我的其他贡献者那里看到其他答案的细微差别很少。