C# 线程池SetMaxThreads和SetMinThreads幻数

C# 线程池SetMaxThreads和SetMinThreads幻数,c#,threadpool,C#,Threadpool,对于设置线程池的SetMaxThreads和SetMinThreads的值,是否有一个神奇的数字或公式?我有数千个需要执行的长时间运行的方法,但就是找不到最适合设置这些值的方法。任何建议都将不胜感激。通常,神奇的数字是不要管它。线程池在处理这方面做得很好 也就是说,如果您正在执行大量长时间运行的服务,和这些服务将有很长的等待时间,您可能需要增加最大线程数以处理更多选项。(如果进程没有阻塞,那么如果增加线程数,可能只会降低速度…) 剖析你的应用程序找到正确的数字。 如果你想要更好的控制,你可能想考

对于设置线程池的SetMaxThreads和SetMinThreads的值,是否有一个神奇的数字或公式?我有数千个需要执行的长时间运行的方法,但就是找不到最适合设置这些值的方法。任何建议都将不胜感激。

通常,神奇的数字是不要管它。线程池在处理这方面做得很好

也就是说,如果您正在执行大量长时间运行的服务,这些服务将有很长的等待时间,您可能需要增加最大线程数以处理更多选项。(如果进程没有阻塞,那么如果增加线程数,可能只会降低速度…)


剖析你的应用程序找到正确的数字。

如果你想要更好的控制,你可能想考虑不使用内置线程池。有一个很好的替换。

默认的最小线程数是您的机器拥有的内核数。这是一个很好的数字,一般来说,运行的线程数超过内核数是没有意义的

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

threadpool计划程序尝试将活动线程的数量限制为最小,默认情况下为您拥有的内核数量。每秒两次,如果活动线程未完成,则允许多启动一个线程。运行很长时间或执行大量不是由I/O引起的阻塞的线程不是线程池的理想候选线程。您应该使用常规线程


达到最大限度是不健康的。在一台四核机器上,仅这些线程的堆栈就将消耗1 GB的虚拟内存空间。很有可能得到OOM。如果这是你的问题,考虑降低最大线程数。或者考虑启动从线程安全队列接收工作包的一些常规线程。

我尝试使用StaskTHealToCub,但没有用。在我将所有工作项排队后,我尝试使用WaitForIdle(我有执行后逻辑要运行),它从不阻塞,只是继续。可能在键盘和电脑之间,但还没有发现雪人知道这篇文章已经有10年了。但不管它值多少钱。。。根据我的专业经验,几乎在所有情况下,如果认为“定制”实现的性能会比.NET团队多年来所做的要好,那么这是一个错误的决定。当然,在某些极端情况下,通用线程池实现可能不理想,但这种情况非常罕见。如果要更改最大线程(和最小线程?),则有两个参数,工作线程和完成端口线程。完成端口线程数是多少?另外,如果我不设置线程池,而不设置最小/最大线程,我会遇到OutOfMemoryException,所有线程都会失败。这是另一个问题-您可以通过限制线程池来减少工作量,但是内存不足真的与线程无关…@ReedCopsey你能帮我吗?Thanksit“限制”工作以避免线程池使用太多线程导致OOM异常不是一个好主意。线程池的思想是管理异步工作负载,因此您应该将“限制”留给线程池,而不是自己来做。如果由于线程池而导致内存不足,您应该减少MaxThreads(1个线程大约需要1 MB)。请看,一位用户建议我应该使用[ThreadPool],根据您的说法,我认为这不是一个好主意,也许您可以帮我。@Hans Passant:这几乎不正确,首先,默认的最大线程数取决于应用程序使用的.NET Framework版本(例如,2.0中每个核心25个)。第二件事是,增加最小线程数会导致线程能够毫不延迟地启动,直到达到最小线程数(如果不需要,它们将不会启动)。如果达到最小延迟,新线程将只在两个线程之间创建一个延迟,导致长操作(>500ms)的性能增加,但短操作的性能下降。@HansPassant-如果创建的线程可能会在等待外部IO时被阻塞,我认为在某些情况下“最佳”最小值确实会高于核心数。因为一个“阻塞”线程仍然朝着最小值“计数”,对吗?(我知道这在几秒钟内不会有什么影响,因为在那之后,调度程序无论如何都会创建这些额外的线程。只是要确保我理解其中的原因。)