创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。