1. ホーム
  2. c#

[解決済み] ThreadPool.QueueUserWorkItem vs Task.Factory.StartNew

2023-08-20 23:10:01

質問

以下の違いは何ですか?

ThreadPool.QueueUserWorkItem

Task.Factory.StartNew

上記のコードが、ある長時間実行されるタスクに対して500回呼ばれた場合、スレッドプールのスレッドはすべて占有されるのでしょうか?

それとも、TPL (2番目のオプション) は、プロセッサの数より少ないか等しいスレッドを占有するのに十分賢いのでしょうか?

どのように解決するのですか?

TPLで長時間実行するタスクを開始する場合は、以下のように指定する必要があります。 TaskCreationOptions.LongRunning と指定すると、その意味は はスレッドプールにスケジュールされないことを意味します。 (EDIT: コメントで指摘されているように、この はスケジューラー固有の決定であり、確実な保証ではありませんが、賢明な運用スケジューラーであれば、スレッドプールで長時間実行するタスクのスケジューリングは避けてほしいと願っています)。

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

スレッドプールのポイントは 短い タスクが、実際に実行されている時間に比べて、新しいスレッドを作成することで大きな打撃を受けることを避けるためです。タスクが長時間実行される場合、新しいスレッドを作成することによる影響はいずれにせよ比較的小さくなります - そして、スレッドプールのスレッドを使い果たす可能性はありません。(今ではその可能性は低くなっていますが、私は を経験しました)。

個人的には、もしオプションがあれば、私は間違いなく TPL を使用します。 Task API は非常に素晴らしいものです。 を実行します。 は、タスクが長時間実行されることをTPLに伝えることを忘れないでください。

EDIT: コメントで指摘されているように、PFX チームのブログ記事も参照してください。 TPL とスレッド プールのどちらを選択するか :

結論から言うと、CLRチームのThreadPool開発者がすでに述べていることを再度説明します。

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

EDIT: また、コメントから、TPLでは、以下のように使用できることを忘れないでください。 カスタムスケジューラ を使用できることも忘れてはいけません。