.NET ThreadPool澄清 - 可用vs空闲线程

时间:2009-01-21 17:20:08

标签: .net multithreading threadpool

我对.NET ThreadPool的一个方面感到有点困惑:即,如何判断有多少“可用”线程是等待重用的空闲线程,以及还有多少尚未创建。

GetAvailableThreads()方法的摘要说明了它:

  

检索之间的差异   最大线程池线程数   由GetMaxThreads方法返回,   和当前活动的数字。

任何“活跃”的线程都在忙着工作,因此无法重复使用,但有多少“可用”可用于“可用”,因为它们尚未创建?

我知道GetMinThreads()方法返回框架将在池中维护以供重用的绝对最小线程数,但这并不一定等于当前空闲线程数 - 是吗?我的印象是,空闲线程会在ThreadPool中徘徊,只有在未使用一段时间后才会被修剪回最小值。

这很重要,因为根据文档:

  

当所有线程池线程都已分配给任务时,线程池不会立即开始创建新的空闲线程。为避免不必要地为线程分配堆栈空间,它会间隔创建新的空闲线程。该间隔目前是半秒,尽管它可能会在.NET Framework的未来版本中发生变化。

我想检查我的应用程序是否必须在池中创建过多的“新”线程 - 减慢它 - 但我不知道如何在不知道有多少空闲的情况下这样做我已经闲逛的准备重用的线程。

欢迎任何想法。谢谢!

2 个答案:

答案 0 :(得分:3)

ThreadPool无法确定当前有多少线程处于空闲状态。也就是说,创建但实际上并没有做任何事情。

我对ThreadPool的经验表明,保持线程非常好。我不知道他们是否已将逻辑放在那里以跟踪正在使用的平均线程数,但我从未注意到我的程序正在等待线程创建。当然,除了在启动时。我的一个程序经常创建和运行几十个并发线程,即使工作负载在一段时间内很低,我也没有看到启动它们的任何延迟。

我建议您检测应用程序,跟踪何时调用ThreadPool.QueueUserWorkItem,以及何时实际启动工作项。像这样:

DateTime queueTime = DateTime.Now;
ThreadPool.QueueUserWorkItem(WorkItemProc, queueTime);

void WorkItemProc(object state)
{
    DateTime startTime = DateTime.Now;
    DateTime queueTime = (DateTime)state;
    TimeSpan elapsed = startTime - queueTime;
    // At this point, elapsed.TotalMilliseconds will tell you how long it took
    // between queuing the item and it actually being started.
    ...
}

如果您发现启动池线程花费的时间太长,那么您应该创建自己的托管线程,并使用事件或其他一些消息传递机制来使其工作。

答案 1 :(得分:1)

我建议这是“如果你不得不问,你没有正确使用它”。如果资源管理是一个问题,那么您应该创建一个专门针对您的性能需求的自定义解决方案。 .net线程池是一种通用工具。

  

it's designed for a collection of independent short-duration tasks.

对于我来说,线程池不会给你设备来限制它,这是你不应该这样做的最佳标志。线程池是标准情况下的纵容工具。但不适用于任何情况。从我的问题来看,我相信,不是为了你的问题。

我建议您阅读Raymond Chen的帖子。并this post by Eric Lippert