C# 当没有更多可用线程时.ForEach循环是否会阻塞

C# 当没有更多可用线程时.ForEach循环是否会阻塞,c#,.net,multithreading,task-parallel-library,synchronizationcontext,C#,.net,Multithreading,Task Parallel Library,Synchronizationcontext,我们有一个.ForEach循环(TPL),它可以启动很多很多很多任务。 由于TPL正在使用线程池中的线程,我想知道当没有更多可用线程时会发生什么? 调用代码是否会阻塞,直到线程再次可用 我知道线程池有一个全局工作队列,工作项(Task)将在其中排队。那队人会排满吗 我们的问题是,有些任务运行时间长(30分钟),有些任务运行时间短(一秒钟),但我们有数千个这样的任务,如果不是更多的话。TPL是否为我启动的每个任务启动一个新线程?我想不是。线程池将在什么时候耗尽?当没有更多空闲线程时,会有几个算法启

我们有一个
.ForEach
循环(TPL),它可以启动很多很多很多任务。 由于TPL正在使用线程池中的线程,我想知道当没有更多可用线程时会发生什么? 调用代码是否会阻塞,直到线程再次可用

我知道线程池有一个全局工作队列,工作项(
Task
)将在其中排队。那队人会排满吗


我们的问题是,有些任务运行时间长(30分钟),有些任务运行时间短(一秒钟),但我们有数千个这样的任务,如果不是更多的话。TPL是否为我启动的每个任务启动一个新线程?我想不是。线程池将在什么时候耗尽?

当没有更多空闲线程时,会有几个算法启动。主要的一点是线程池将缓慢地创建额外的线程(最多2个/秒)

这有助于解决长期运行任务的情况,但系统并不完美。如果创建了数百个线程,您的应用程序可能会崩溃

第一种方法是在ForEach上指定DegreeOfParallelism。您希望将线程数限制为
numberOfCores*someFactor
,其中someFactor取决于任务执行的I/O


你也可以调查定制的第三方物流调度器,我对此不太了解

幸好你笑了。默认的MaxThreads非常高,你不想弄乱它。我不认为你真正回答了OP的问题。“这个队列会满吗?”回答应该是否定的(从技术上讲,如果你耗尽了计算机内存,或者某个阵列上的2gb限制,但我们将忽略它),“线程池将在什么时候耗尽?“线程池将仅创建MaxThreads线程。之后,您的新任务将全部排队等待免费线程。谢谢。任务将排队,是的,但是调用代码会发生什么?它会因为没有线程而阻塞吗?John,调用代码总是在Parallel.ForEach()上阻塞,例如,它允许您将其包装在try/catch中。如果要释放主线程,请从单独的任务运行它。@Jonathan-主要内存(1 MB/线程)。在32位上,您永远无法访问maxThreads。大量的(排队的)任务通常是可以的。