ThreadPool没有立即启动新线程

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

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

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

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

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

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

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

至于为何遇到延迟, ThreadPool类的MSDN文档说明如下:

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

您只知道ThreadPool没有达到其最大线程数,而不是它实际上空闲的线程数(如果有的话)。

线程池的最大线程数值是它可以创建的最大数量。 它不是已创建的最大数量。 线程池具有逻辑,可防止它立即激活一大堆线程。

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

我似乎记得延迟是500毫秒,但我找不到文档来validation。

它是: 托管线程池 :

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

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

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