为什么ThreadPool.SetMinThreads没有改变最小值?

时间:2013-02-11 22:11:18

标签: c# performance threadpool

使用.NET 4.0运行时编译并运行,我有这样的代码:

int MinWorkerThreads, MaxWorkerThreads;
int MinCompletionPortThreads, MaxCompletionPortThreads;
ThreadPool.GetMinThreads(out MinWorkerThreads, out MinCompletionPortThreads);
ThreadPool.GetMaxThreads(out MaxWorkerThreads, out MaxCompletionPortThreads);
_logger.Info("Default thread pool settings min/max:");
_logger.Info("Worker thread: " + MinWorkerThreads + " / " + MaxWorkerThreads);
_logger.Info("IO thread    : " + MinCompletionPortThreads + " / " + MaxCompletionPortThreads);
_logger.Info("Setting minimum default worker thread count to " + Config.MinWorkerThreads);
if (!ThreadPool.SetMinThreads(Config.MinWorkerThreads, MinCompletionPortThreads))
{
    _logger.Warn("Unable to modify the minimum number of worker threads");
}
ThreadPool.GetMinThreads(out MinWorkerThreads, out MinCompletionPortThreads);
_logger.Info("Worker thread: " + MinWorkerThreads + " / " + MaxWorkerThreads);

我的日志输出如下所示:

Default thread pool settings min/max:
Worker thread: 4 / 32767
IO thread    : 4 / 1000
Setting minimum default worker thread count to 50
Worker thread: 50 / 32767

该值会立即更改,但不会永久更改。

为什么我这样做? Timer使用默认的ThreadPool,我已经看到突然批量任务进入系统线程池,淹没它的时间,导致一些应该每15秒触发一次的定时器延迟超过60秒。

问题在于,当我将相同的信息转储到运行时十五分钟后,使用相同的代码,我得到了非常不同的值:

Worker thread: 4 / 400
IO thread    : 4 / 400

有没有更好的方法来解决此问题而不放弃使用System.Timers.Timer?什么会在一个完全不涉及IIS的独立C#应用程序中重置此值?如果您是自托管ASP.NET,那会隐式更改系统线程池的调优吗?

1 个答案:

答案 0 :(得分:3)

我建议采用另一种方法。

从ThreadPool中删除所有阻止代码。这不是它的设计目标。

如果您有IO绑定操作,请在每个阶段进行异步操作。

如果您有CPU绑定操作,请不要在ThreadPool线程中运行它们。

严格遵循这些规则,您永远不需要使用ThreadPool参数。正如您所注意到的,有太多的.Net API完全依赖于响应式ThreadPool。如果你只是吞噬线程,很可能无论你选择多少,如果你运行你的程序很长/很难,你将再次达到极限。

按预期使用ThreadPool ......短暂的逻辑,主要用于将IO结果编组到正确的位置。