2010-01-11 96 views
26

是否有一个幻数或公式用于设置ThreadPool的SetMaxThreads和SetMinThreads的值?我有成千上万的需要执行的长时间运行的方法,但是却无法找到设置这些值的完美匹配。任何意见将不胜感激。ThreadPool SetMaxThreads和SetMinThreads Magic Number

回答

39

线程的默认最小数量是您的机器具有的核心数量。这是一个很好的数字,运行比核心更多的线程通常并不合适。

线程的默认最大数量是您在.NET 2.0 SP1及更高版本上具有的核心数量的250倍。这里有大量的呼吸室。在四核机器上,如果没有任何线程在合理的时间内完成,则需要499秒达到最大值。

线程池调度程序尝试将活动线程的数目限制为最小值,默认情况下为您拥有的核心数。如果活动线程没有完成,它允许一秒多线程启动。运行了很长时间的线程或做了很多非I/O引起的阻塞并不适合线程池。您应该使用常规线程来代替。

达到最大值并不健康。在四核心机器上,这些线程的堆栈将消耗千兆字节的虚拟内存空间。获得OOM很可能。如果这是您的问题,请考虑降低最大线程数。或者考虑从几个线程安全队列中接收几个接收工作包的常规线程。

+0

请看看[我的相关问题](http://stackoverflow.com/q/7974559/75500“运行一批进程并报告每个进程的进度“),一位用户在那里建议我应该使用[ThreadPool],根据你的说法,我认为这不是一个好主意,也许你可以帮助我。 – Shimmy 2011-11-03 01:39:25

+3

@Hans Passant:这几乎是正确的,首先t他默认的最大线程数取决于应用程序使用的.NET Framework版本(例如, 2.0每个核心25个)。第二件事是,增加线程的最小数量会导致线程无延迟地启动,直到达到最小数量(如果不需要,它们不会启动)。如果达到最小延迟时间,新线程将只在延迟时间内创建,导致长时间运行(> 500毫秒)时性能提高,但在短时间运行时性能下降。 – haze4real 2012-11-09 00:14:10

+0

@HansPassant - 如果创建可能被阻塞等待外部IO的线程,我认为有些情况下“最佳”最小值确实会高于核心数量。因为“阻塞”线程仍然“计数”到最低限度,对吧? (我知道这不会超过几秒钟,因为在此之后,调度器将创建这些额外的线程,只要确保我理解了推理。) – ToolmakerSteve 2018-03-04 18:18:38

6

通常情况下,幻数是让它独自一人。 ThreadPool在处理这个方面做得很好。这就是说,如果你正在做很多长时间运行的服务,那么这些服务将有很长的等待时间,你可能想要增加最大的线程来处理更多的选项。 (如果进程没有被阻塞,如果你增加线程数,你可能会放慢速度...)

配置文件以查找正确的编号。

+0

如果我要更改最大线程(和最小线程?),则有两个参数,工作线程和完成端口线程。什么是完成端口线程计数? – Benny 2010-01-11 18:42:49

+0

另外,如果我单独离开ThreadPool,而不设置最小/最大线程,则会遇到OutOfMemoryException,并且所有线程都会失败。 – Benny 2010-01-11 18:44:55

+3

这是一个不同的问题 - 你可以通过限制它来减少工作量,但是内存耗尽与线程无关...... – 2010-01-11 20:14:05

5

如果您想要更好的控制,您可能需要考虑不使用内置的ThreadPool。在http://www.codeproject.com/KB/threads/smartthreadpool.aspx有一个很好的替代品。

+0

我试图使用SmartThreadPool,但无济于事。在排队所有工作项后,我尝试使用WaitForIdle(我有执行后逻辑来运行),它从不阻止,只是向右移动。可能是在键盘和电脑之间,但还没有想出那一个呢 – Benny 2010-01-11 18:41:43