更新-質問のタイトルを変更して、私が本当に求めているものを反映させました
次のコードについて考えてみます。
// this query generates 12 instances of Func<int>, which each when executed
// print something to the console and wait for 1 second.
var actions = Enumerable.Range(0, 12).Select(i => new Func<int>(() =>
{
Console.WriteLine("{0} - waiting 1 sec", i);
Thread.Sleep(1000);
return 1;
}));
// define a parallel query. Note the WithDegreeOfParallelism call here.
var query = from action in actions.AsParallel().WithDegreeOfParallelism(12)
select action();
// execute, measuring total duration
var stopw = Stopwatch.StartNew();
query.ToList();
Console.WriteLine(stopw.Elapsed);
Console.WriteLine(Environment.ProcessorCount); // 3 on my machine
の呼び出しを省略するとWithDegreeOfParallelism
、これは4つのチャンクで実行され、合計で約4秒かかります。これは、CPUカウントが3であるため、予想されることです。
ただし、4を超える番号で呼び出すWithDegreeOfParallelism
と、常に3つのチャンクが取得され、合計時間は3秒未満にはなりません。値が12の場合、合計時間は(1秒強)1秒になると思います。
私は何が欠けていますか?そして、CPUを集中的に使用しない4つ以上のタスクの並列実行を強制するにはどうすればよいですか?
更新:もちろん手動でスレッドをスピンアップすることに戻ることもできますが、新しいPFXライブラリによってこれが少し簡単になることを期待していました...とにかく、以下のコードは約1秒の合計実行時間を与えます
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 12; i++)
{
int i1 = i;
threads.Add(new Thread(() =>
{
Console.WriteLine(i1);
Thread.Sleep(1000);
}));
}
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());