web-dev-qa-db-ja.com

ThreadPool.QueueUserWorkItemとTask.Factory.StartNew

以下の違いは何ですか

ThreadPool.QueueUserWorkItem

Task.Factory.StartNew

長時間実行されているタスクで上記のコードが500回呼び出された場合、すべてのスレッドプールスレッドが使用されますか?

または、TPL(2番目のオプション)は、プロセッサの数以下のスレッドを使用するのに十分にスマートですか?

73

TPLで長時間実行されるタスクを開始する場合は、 TaskCreationOptions.LongRunning 、つまり、スレッドプールでスケジュール(しない) (編集:コメントに記載されているように、これはスケジューラ固有の決定であり、ハードで高速な保証ではありませんが、賢明なプロダクションスケジューラは、スレッドプールで長時間実行されるタスクをスケジュールすることを避けます。

スレッドプールで長時間実行される多数のタスクを自分でスケジュールしないでください。最近では、スレッドプールのデフォルトサイズはかなり大きいと思います(この方法で悪用されることが多いため)が、基本的にはこのように使用すべきではありません。

スレッドプールのポイントは、shortのタスクが実際に実行されている時間と比較して、新しいスレッドの作成から大きな打撃を受けることを避けることです。タスクが長時間実行される場合、新しいスレッドを作成することの影響はとにかく比較的小さくなります-そして、スレッドプールスレッドが不足する可能性はありません。 (今はあまりありませんが、私didは以前のバージョンの.NETでそれを経験します。)

個人的には、オプションがあれば、Task AP​​Iがかなりいいという理由でTPLを間違いなく使用しますが、do覚えておいてくださいタスクが長時間実行されることをTPLに伝えるため。

編集:コメントに記載されているように、PFXチームの TPLとスレッドプールの選択 :に関するブログ投稿も参照してください。

結論として、CLRチームのThreadPool開発者がすでに述べたことを繰り返します。

Task is now the preferred way to queue work to the thread pool.

編集:また、コメントから、TPLで カスタムスケジューラ を使用できることを忘れないでください。

89
Jon Skeet