12

TPL を使用して、関数を使用して新しいタスクをシステム スレッド プールに追加していますTask.Factory.StartNew()。唯一の問題は、多くのスレッドを追加していて、プロセッサが処理するには多すぎると思うことです。このスレッド プールに最大スレッド数を設定する方法はありますか?

4

4 に答える 4

16

デフォルト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 を使用するため、サイズを小さく設定しすぎると、飢餓などの副作用が発生する可能性があります。

于 2012-08-09T07:43:06.800 に答える
7

通常、TPLは適切な「デフォルト」スレッドプールサイズを決定します。本当に必要なスレッドが少ない場合は、「方法:同時実行の程度を制限するタスクスケジューラを作成する」を参照してください。

于 2012-06-17T23:49:53.853 に答える
4

最初にパフォーマンスの問題を調査する必要があります。使用率の低下につながる可能性のあるさまざまな問題があります。

  • LongRunningTaskオプションを使用せずに長時間実行タスクをスケジュールする
  • 同じWebアドレスへの3つ以上の同時接続を開こうとしています
  • 同じリソースへのアクセスをブロックする
  • 複数のスレッドからInvoke()を使用してUIスレッドにアクセスしようとしています

いずれにせよ、並行タスクの数を減らすだけでは対処できないスケーラビリティの問題があります。プログラムは、将来、2コア、4コア、または8コアのマシンで実行される可能性があります。スケジュールされたタスクの数を制限すると、CPUリソースの浪費につながるだけです。

于 2012-06-19T07:58:10.137 に答える