Thread.Start() versus ThreadPool.QueueUserWorkItem()



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方法。

托管线程池在何时不使用线程池方面有一些非常好的指导原则。

根据我的经验,当您需要一个持久的、专用的、长时间运行的线程时,您需要创建自己的线程。对于其他一切,请使用异步委托或类似QueueUserWorkItemBackgroundWorker或.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线程位于多线程单元中。

  • 您需要有一个与线程相关联的稳定标识,或者将线程专用于任务。

参考链接。

相关内容

  • 没有找到相关文章

最新更新