Microsoft.NET基类库提供了几种创建线程并启动线程的方法。基本上,调用与其他提供相同服务的调用非常相似:创建一个表示执行流(或多个)的对象,为其分配一个表示要执行的执行流的委托,最终,根据委托签名,作为参数的对象。
嗯,有两种方法(本质上):
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)的原因有什么特殊的吗?
- 性能原因
- 模式
- 什么是最好的方法
我觉得答案是:"视情况而定"。你能列出一些情况吗,其中一种方法比另一种更好?
启动一个新线程可能是一项非常昂贵的操作。线程池重用线程,从而分摊成本。除非您需要一个专用线程,否则建议使用线程池。通过使用专用线程,您可以更好地控制线程特定的属性,如优先级、区域性等。此外,您不应该在线程池上执行长时间运行的任务,因为这会迫使线程池生成额外的线程。
除了您提到的选项之外,.NET4还提供了一些很棒的并发抽象。检查Task和Parallel类以及所有新的PLINQ方法。
托管线程池在何时不使用线程池方面有一些非常好的指导原则。
根据我的经验,当您需要一个持久的、专用的、长时间运行的线程时,您需要创建自己的线程。对于其他一切,请使用异步委托或类似QueueUserWorkItem
、BackgroundWorker
或.NET 4.0中与任务相关的功能。
ThreadPool中的线程是后台线程;由新Thread对象创建和启动的所有线程都是前台线程。
后台线程不会保持托管执行环境的运行。
参考http://msdn.microsoft.com/en-us/library/h339syd0.aspx了解更多信息。
在.NET 4.5.2中,他们添加了一个新方法:HostingEnvironment.QueueBackgroundWorkItem.
这似乎是ThreadPool.QueueUserWorkItem
的替代方案。两者的行为相似,但在ASP.NET中使用新方法有一些好处:
HostingEnvironment.QueueBackgroundWorkItem方法允许安排小的后台工作项目。ASP.NET跟踪这些项目防止IIS突然终止工作进程,直到所有后台工作项已完成。无法调用此方法在ASP.NET托管应用程序域之外。
使用ThreadPool,可以减少对线程系统的控制。这是为了简化您的流程而进行的权衡。如果你从ThreadPool中获得了所有需要的东西,你应该可以随意使用它。如果你需要对线程进行更多的控制,那么你当然需要使用Thread类。
ThreadPool.QueueUserWorkItem()基本上适用于即发即弃场景,此时应用程序不取决于操作是否完成。
使用经典线程进行细粒度控制。
您应该使用ThreadPool.QueueUserWorkItem
,以下情况除外:
-
您需要一个前台线程。
-
您需要一个线程具有特定的优先级。
-
您的任务会导致线程长时间阻塞时间线程池具有最大线程数,因此被阻止的线程池线程数可能会阻止任务启动。
-
您需要将线程放置到单线程单元中。全部的ThreadPool线程位于多线程单元中。
-
您需要有一个与线程相关联的稳定标识,或者将线程专用于任务。
参考链接。