创建线程- Task.Factory.StartNew vs new Thread()
本文关键字:new Thread vs StartNew 线程 Task Factory 创建 | 更新日期: 2023-09-27 18:12:14
我正在学习。net 4中新的线程和并行库
在过去,我会创建一个新的线程,像这样(作为一个例子):
DataInThread = new Thread(new ThreadStart(ThreadProcedure));
DataInThread.IsBackground = true;
DataInThread.Start();
现在我可以做:
Task t = Task.Factory.StartNew(() =>
{
ThreadProcedure();
});
有什么区别?
谢谢
差别很大。任务被安排在ThreadPool上,如果合适的话,甚至可以同步执行。
如果你有一个长时间运行的后台工作,你应该通过使用正确的任务选项来指定它。
你应该选择任务并行库而不是显式线程处理,因为它更优化。你也有更多的功能,如延续。
任务为您提供了任务API的所有优点:
- 添加续列(
Task.ContinueWith
) - 等待多个任务完成(全部或任何)
- 捕获任务中的错误并稍后询问它们
- 捕获取消(并允许您指定取消开始)
- 可能有返回值 在c# 5中使用await
- 更好地控制调度(如果要长时间运行,在创建任务时要这样说,以便任务调度程序可以考虑到这一点)
请注意,在这两种情况下,您都可以使用方法组转换使代码稍微简单一些:
DataInThread = new Thread(ThreadProcedure);
// Or...
Task t = Task.Factory.StartNew(ThreadProcedure);
在第一种情况下,你只是开始一个新线程,而在第二种情况下,你正在进入线程池。
线程池任务是共享和回收线程。它可以避免每次我们需要创建一个新线程时损失几毫秒的时间。
有几种进入线程池的方法:
- 使用TPL(任务并行库),就像你做的那样 通过调用ThreadPool。QueueUserWorkItem
- 通过在委托 上调用BeginInvoke
- 当你使用BackgroundWorker
你的第一个代码块告诉CLR创建一个线程(比如。T),它可以作为后台运行(调度T时使用线程池线程)。简而言之,你显式地要求CLR为你创建一个线程来做一些事情,并在线程上调用Start()方法来启动。
你的第二个代码块做同样的事情,但委托(隐式移交)创建线程(后台-再次在线程池中运行)的责任,并通过任务工厂实现中的StartNew方法启动线程。
这是给定代码块之间的快速区别。话虽如此,你可以在谷歌上搜索或从我的同事那里看到其他答案。