TPL を使用して、関数を使用して新しいタスクをシステム スレッド プールに追加していますTask.Factory.StartNew()
。唯一の問題は、多くのスレッドを追加していて、プロセッサが処理するには多すぎると思うことです。このスレッド プールに最大スレッド数を設定する方法はありますか?
4 に答える
デフォルトTaskScheduler
( から取得TaskScheduler.Default
) は (内部クラス) 型ThreadPoolTaskScheduler
です。この実装では、ThreadPool
クラスを使用してタスクをキューに入れます (Task
で作成されていないTaskCreationOptions.LongRunning
場合 - この場合、タスクごとに新しいスレッドが作成されます)。
したがって、Task
経由で作成されたオブジェクトで使用できるスレッドの数を制限したい場合new Task(() => Console.WriteLine("In task"))
は、次のようにグローバル スレッドプールで使用できるスレッドを制限できます。
// Limit threadpool size
int workerThreads, completionPortThreads;
ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
workerThreads = 32;
ThreadPool.SetMaxThreads(workerThreads, completionPortThreads);
への呼び出しThreadPool.GetMaxThreads()
は、 の縮小を避けるために行われcompletionPortThreads
ます。
これは悪い考えである可能性があることに注意してください - 指定されたスケジューラーのないすべてのタスク、および任意の数の他のクラスがデフォルトの ThreadPool を使用するため、サイズを小さく設定しすぎると、飢餓などの副作用が発生する可能性があります。
通常、TPLは適切な「デフォルト」スレッドプールサイズを決定します。本当に必要なスレッドが少ない場合は、「方法:同時実行の程度を制限するタスクスケジューラを作成する」を参照してください。
最初にパフォーマンスの問題を調査する必要があります。使用率の低下につながる可能性のあるさまざまな問題があります。
- LongRunningTaskオプションを使用せずに長時間実行タスクをスケジュールする
- 同じWebアドレスへの3つ以上の同時接続を開こうとしています
- 同じリソースへのアクセスをブロックする
- 複数のスレッドからInvoke()を使用してUIスレッドにアクセスしようとしています
いずれにせよ、並行タスクの数を減らすだけでは対処できないスケーラビリティの問題があります。プログラムは、将来、2コア、4コア、または8コアのマシンで実行される可能性があります。スケジュールされたタスクの数を制限すると、CPUリソースの浪費につながるだけです。