これを次のコードでテストしました。
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 になります。
しかし、待つだけのスレッドを何十個も持つことは、特にメモリ消費に関しては非常に非効率的です。代わりに非同期メソッドの使用を検討する必要があります。