ThreadPool没有立即启动新线程

时间:2011-09-29 17:00:40

标签: c# multithreading console-application

我有一个C#Windows服务,可以启动各种对象(类库)。这些对象中的每一个都有自己的“处理”逻辑,通过使用ThreadPool启动多个长时间运行的处理线程。我有一个例子,就像这样:

System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(WorkerThread_Processing));

这很有效。我的应用程序没有任何问题,我的线程运行良好。

现在,对于回归测试,我启动了相同的对象,但是从C#Console应用程序而不是Windows服务。它调用相同的确切代码(因为它调用相同的对象),但WorkerThread_Processing方法在启动前延迟最多20秒。

我已经进入并从ThreadPool切换到Thread,问题就消失了。这可能发生什么?我知道我没有超过MaxThreads计数(我最多开始20个线程)。

2 个答案:

答案 0 :(得分:15)

ThreadPool特别是用于长期运行的项目(更具体地说,当您使用ThreadPool时,您甚至不一定要启动新线程,它的目的是将任务分布在有限数量的线程上。)

如果您的任务长时间运行,您应该将其分解为放在ThreadPool上的逻辑部分(或使用新的Task框架),或者启动您自己的{{1对象。

至于为什么您遇到了延迟,MSDN Documentation for the ThreadPool class说明了以下内容:

  

作为其线程管理策略的一部分,线程池在创建线程之前会延迟。因此,当许多任务在短时间内排队时,在所有任务开始之前可能会有很长的延迟。

您只知道Thread尚未达到其最大线程数,而不是它实际处于空闲状态的线程数(如果有)。

答案 1 :(得分:2)

线程池的最大线程数值是它可以创建的最大数量。它不是已创建的最大数量。线程池有逻辑阻止它立即旋转一大堆线程。

如果快速连续调用ThreadPool.QueueUserWorkItem 10次,则线程池不会立即创建10个线程。它会启动一个线程,延迟,启动另一个等等。

我似乎记得延迟是500毫秒,但我找不到要验证的文档。

这是:The Managed Thread Pool

  

线程池有内置延迟(在.NET中半秒)   框架版本2.0)在启动新的空闲线程之前。如果你的   应用程序会在短时间内定期启动许多任务   空闲线程数量的增加可以产生显着的   吞吐量增加。设置空闲线程数太高   不必要地消耗系统资源。

     

您可以控制线程维护的空闲线程数   使用GetMinThreads和SetMinThreads

进行池化

请注意,此引用来自.NET 3.5版本的文档。 .NET 4.0版本没有提到延迟。