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委托或类似QueueUserWorkItemBackgroundWorker或.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()基本上用于“即发即忘”的情况,当应用程序不依赖于操作是否完成。

使用经典线程进行细粒度控制。