[英]ThreadPool not starting new Thread instantly
我有一个启动各种对象(类库)的 C# Windows 服务。 这些对象中的每一个都有自己的“处理”逻辑,这些逻辑通过使用ThreadPool
启动多个长时间运行的处理线程。 我有一个例子,就像这样:
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(WorkerThread_Processing));
这很好用。 我的应用程序没有问题,我的线程运行良好。
现在,对于回归测试,我从 C# 控制台应用程序而不是 Windows 服务启动这些相同的对象。 它调用完全相同的代码(因为它正在调用相同的对象),但是WorkerThread_Processing
方法在启动前最多延迟 20 秒。
我已经进入并从ThreadPool
切换到Thread
,问题就消失了。 这里会发生什么? 我知道我没有超过MaxThreads
计数(我最多启动 20 个线程)。
ThreadPool
特别不适合长时间运行的项目(更具体地说,当您使用ThreadPool
时,您甚至不必启动新线程,因为它的目的是将任务分散到有限数量的线程上)。
如果您的任务长时间运行,您应该将其分解为放置在ThreadPool
上的逻辑部分(或使用新的Task
框架),或者启动您自己的Thread
对象。
至于为什么遇到延迟, ThreadPool
类的MSDN 文档说明如下:
作为其线程管理策略的一部分,线程池在创建线程之前会延迟。 因此,当大量任务在短时间内排队时,在所有任务开始之前可能会有明显的延迟。
您只知道ThreadPool
尚未达到其最大线程数,而不知道它实际上有多少线程(如果有)处于空闲状态。
线程池的最大线程数值是它可以创建的最大数量。 它不是已创建的最大数量。 线程池具有防止它立即启动一大堆线程的逻辑。
如果快速连续调用ThreadPool.QueueUserWorkItem
10 次,线程池不会立即创建 10 个线程。 它将启动一个线程,延迟,启动另一个等。
我似乎记得延迟是 500 毫秒,但我找不到文档来验证这一点。
这是: 托管线程池:
在启动新的空闲线程之前,线程池具有内置延迟(在 .NET Framework 2.0 版中为半秒)。 如果您的应用程序在短时间内周期性地启动许多任务,空闲线程数量的小幅增加可以显着增加吞吐量。 将空闲线程的数量设置得太高会不必要地消耗系统资源。
您可以使用 GetMinThreads 和 SetMinThreads 控制线程池维护的空闲线程数
请注意,此引用取自 .NET 3.5 版本的文档。 .NET 4.0 版本没有提到延迟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.