繁体   English   中英

ThreadPool 不会立即启动新线程

[英]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对象。

至于为什么遇到延迟, ThreadPoolMSDN 文档说明如下:

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

您只知道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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM