Thread.Start()与ThreadPool.QueueUserWorkItem()
Microsoft .NET Base Class Library提供了几种创build线程的方法并启动它。 基本上,调用与提供相同types的服务的每一个非常相似:创build一个表示执行stream(或更多)的对象,为其分配一个表示要执行的执行stream的委托,并最终根据委托签名,作为参数。
那么,有两种方法(基本上):
1)使用System.Threading.Thread
类。
Thread curr = new Thread(myfunction); /* In a class, myfunction is a void taking an object */ curr.Start(new Object()); /* Or something else to be downcast */
2)使用System.Threading.ThreadPool
类。
ThreadPool.QueueUserWorkItem(myfunction, new Object()); /* Same philosophy here */
有什么特别的原因,我应该使用1)或2)? 性能的原因? 模式? 什么是最好的方法?
我有一种感觉,答案是:“依情况而定”。 你可以列举一种方法比另一种更好的情况吗?
开始一个新的线程可能是一个非常昂贵的操作。 线程池重用线程,从而分摊成本。 除非需要专用线程,否则线程池是推荐的方法。 通过使用专用线程,您可以更好地控制线程特定的属性,如优先级,文化等等。 此外,您不应该在线程池上执行长时间运行的任务,因为它会强制池产生其他线程。
除了你提到的选项,.NET 4还提供了一些非常好的并发抽象。 检查任务和并行类以及所有新的PLINQ方法。
Managed Thread Pool在不使用线程池的时候有一些非常好的指导。
根据我的经验,当你需要一个持久的,专用的,长期运行的线程时,你想创build自己的线程。 对于其他任何事情,请使用asynchronous委托或类似QueueUserWorkItem
, BackgroundWorker
或.NET 4.0的任务相关function。
ThreadPool中的线程是后台线程; 由一个新的Thread对象创build和启动的所有线程都是前台线程。
后台线程不保持托pipe的执行环境运行。
有关更多信息,请参阅http://msdn.microsoft.com/zh-CN/library/h339syd0.aspx 。
在.NET 4.5.2中,他们添加了一个新的方法: HostingEnvironment.QueueBackgroundWorkItem 。
这似乎是ThreadPool.QueueUserWorkItem
的替代方法。 两者的行为相似,但在ASP.NET中使用新方法有一些好处:
HostingEnvironment.QueueBackgroundWorkItem方法可让您安排小型后台工作项目。 ASP.NET跟踪这些项目并防止IIS突然终止工作进程,直到完成所有后台工作项目。 此方法不能在ASP.NET托pipe的应用程序域之外调用。
使用ThreadPool,您对线程系统的控制较less。 这是一个权衡,以简化你的过程。 如果你拥有ThreadPool所需的所有东西,你可以随意使用它。 如果你需要更多的线程控制,那么你当然需要使用Thread类。
ThreadPool.QueueUserWorkItem()基本上用于“即发即忘”的情况,当应用程序不依赖于操作是否完成。
使用经典线程进行细粒度控制。