0

我对 .NET ThreadPool 的一个方面有点困惑:即,您如何知道它的“可用”线程中有多少是等待重用的空闲线程,还有多少尚未创建。

GetAvailableThreads()方法的摘要指出:

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

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

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

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

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

我想检查我的应用程序是否必须在池中创建过多的“新”线程 - 减慢它的速度 - 但我不确定如何做到这一点,而无法弄清楚有多少空闲,准备就绪-重用我闲逛的线程。

欢迎任何想法。谢谢!

4

2 回答 2

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.
    ...
}

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

于 2009-01-21T17:36:13.573 回答
1

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

它是为一组独立的短期任务而设计的。

线程池没有为您提供限制它的工具,对我来说,这是您不应该这样做的最好迹象。线程池是标准情况下的纵容工具。但不适用于任何情况。从你的问题来看,我相信,这不适合你。

我建议您阅读我在上面链接的 Raymond Chen 的帖子。还有Eric Lippert 的这篇文章

于 2009-01-21T19:39:54.137 回答