C# 线程池未立即启动新线程
我有一个C#Windows服务,可以启动各种对象(类库)。每个对象都有自己的“处理”逻辑,通过使用C# 线程池未立即启动新线程,c#,multithreading,console-application,C#,Multithreading,Console Application,我有一个C#Windows服务,可以启动各种对象(类库)。每个对象都有自己的“处理”逻辑,通过使用ThreadPool启动多个长时间运行的处理线程。我有一个例子,就像这样: System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(WorkerThread_Processing)); 这很有效。我的应用程序工作正常,线程工作正常 现在,对于回归测试,我正在启动这些相同的对象,但是是从C#Con
ThreadPool
启动多个长时间运行的处理线程。我有一个例子,就像这样:
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(WorkerThread_Processing));
这很有效。我的应用程序工作正常,线程工作正常
现在,对于回归测试,我正在启动这些相同的对象,但是是从C#Console应用程序而不是Windows服务启动的。它调用相同的精确代码(因为它调用的是相同的对象),但是WorkerThread\u Processing
方法在启动前会延迟20秒
我已经进入并从
线程池
切换到线程
,问题就消失了。这里会发生什么?我知道我没有超过MaxThreads
计数(我最多开始20个线程)。ThreadPool
特别不适用于长时间运行的项目(更具体地说,当您使用线程池时,您甚至不必启动新线程,因为它的目的是将任务分散到有限数量的线程上)
如果您的任务是长时间运行的,您应该将其分解为放在线程池
上的逻辑部分(或者使用新的任务
框架),或者旋转您自己的线程
对象
至于您为什么会遇到延迟,报告如下所示:
作为其线程管理策略的一部分,线程池在创建线程之前会延迟。因此,当许多任务在短时间内排队时,在所有任务启动之前可能会有明显的延迟
您只知道ThreadPool
尚未达到其最大线程数,而不知道有多少线程(如果有)它实际上处于空闲状态。线程池的“最大线程数”值是它可以创建的最大线程数。它不是已经创建的最大线程数。线程池具有防止它立即旋转整个线程组的逻辑
如果连续快速调用ThreadPool.QueueUserWorkItem
10次,线程池将不会立即创建10个线程。它将启动一个线程、延迟、启动另一个线程等
我似乎记得延迟是500毫秒,但我找不到文档来验证这一点
给你:
线程池具有内置延迟(在.NET中为半秒)
在启动新的空闲线程之前,如果
应用程序在很短的时间内周期性地启动许多任务,时间很短
空闲线程数量的增加会产生显著的影响
吞吐量增加。将空闲线程数设置得过高
不必要地消耗系统资源
您可以控制线程维护的空闲线程数
通过使用GetMinThreads和SetMinThreads
请注意,此引文摘自.NET 3.5版本的文档。好的,谢谢您提供的信息!我将用Thread对象替换它们,并查看Task对象以供将来开发。谢谢!但是如果有延迟,为什么会导致延迟(假设有延迟)池中剩余的空闲线程?我同意这个结论,但没有找到令人满意的答案来回答原因。@pst:你不知道池中还有空闲线程,你知道ThreadPool
尚未达到其最大线程数。根据,ThreadPool
将延迟创建新的threads,所以一次添加几个项目几乎肯定会导致延迟。请参阅我的编辑。谢谢!@Adam Robinson更透彻的回答,+1。这绝对不应该发生,我也不会发生。你的控制台应用程序还做了什么吗?如果你创建一个全新的控制台应用程序并放入ThreadPool.QueueUserWorkItem(o=>Console.WriteLine(“测试”))
它是否做了同样的事情?另外,如果您想查看线程池正在做什么,我建议您运行Process Explorer,并密切关注进程中的线程。您可以看到有多少线程池线程正在旋转。如果您的操作需要很长时间才能完成,则可能需要一段时间才能快速增加到20个线程。需要注意的一点是ThreadPool.SetMinThreads
实际上并没有增加线程池中维护的空闲线程数。这只是意味着,当实际线程数低于该数字时,线程池将根据需要创建新线程,而不是等待前一个线程完成。