我使用以下代码对此进行了测试:
var lines = Enumerable.Range(0, 200).ToArray();
int currentThreads = 0;
int maxThreads = 0;
object l = new object();
lines.AsParallel().WithDegreeOfParallelism(100).ForAll(
s =>
{
lock (l)
{
currentThreads++;
if (currentThreads > maxThreads)
{
maxThreads = currentThreads;
Console.WriteLine(maxThreads);
}
}
Thread.Sleep(3000);
lock (l)
{
currentThreads--;
}
});
Console.WriteLine();
Console.WriteLine(maxThreads);
基本上,它记录当前并发执行的迭代次数,然后保存遇到的最大值。
结果变化很大,在 15 到 25 之间,但它总是比我的计算机的 CPU 数量 (4) 多得多。增加睡眠时间会增加最大并发线程数。所以看起来这里的限制因素是ThreadPool
:它会缓慢地创建新线程,尤其是当作业完成相对较快时。
如果要增加使用的线程数,则需要使用SetMinThreads()
(not SetMaxThreads()
)。如果我将最小值设置为 50,则实际使用的线程数约为 60。
但是拥有几十个只做等待的线程是非常低效的,尤其是在内存消耗方面。您应该考虑改用异步方法。