ここでの他の回答は、最も重要な点を省略しているようです:
低負荷のサイトで CPU を集中的に使用する操作をより高速に実行するために並列化しようとしている場合を除き、ワーカー スレッドを使用する意味はまったくありません。
これは、 によって作成されたフリー スレッドと、要求に応答するnew Thread(...)内のワーカー スレッドの両方に当てはまります。ThreadPoolQueueUserWorkItem
はい、確かに、あまりにも多くの作業項目をキューに入れることで、ASP.NET プロセスを枯渇させる可能性があります。ThreadPoolこれにより、ASP.NET がそれ以上の要求を処理できなくなります。この記事の情報はその点で正確です。に使用されるのと同じスレッド プールが、QueueUserWorkItem要求の処理にも使用されます。
しかし、実際にこの枯渇を引き起こすのに十分な作業項目をキューに入れている場合は、スレッド プールを枯渇させているはずです! 文字通り何百もの CPU 集中型の操作を同時に実行している場合、マシンが既に過負荷になっているときに、ASP.NET 要求を処理する別のワーカー スレッドを用意してもよいでしょうか? このような状況に陥っている場合は、完全に再設計する必要があります。
マルチスレッド コードが ASP.NET で不適切に使用されているのを見たり聞いたりすることがほとんどです。これは、CPU を集中的に使用する作業をキューに入れるためのものではありません。これは、I/O バウンドの作業をキューに入れるためのものです。また、I/O 作業を行う場合は、I/O スレッド (I/O 完了ポート) を使用する必要があります。
具体的には、使用しているライブラリ クラスでサポートされている非同期コールバックを使用する必要があります。これらのメソッドは常に非常に明確にラベル付けされています。それらは単語Beginとで始まりますEnd。、、、Stream.BeginReadなど。Socket.BeginConnect_WebRequest.BeginGetResponse
これらのメソッドはを使用しますが、ASP.NET 要求に干渉しないThreadPoolIOCP を使用します。これらは、I/O システムからの割り込み信号によって「起動」できる特別な種類の軽量スレッドです。また、ASP.NET アプリケーションでは、通常、ワーカー スレッドごとに 1 つの I/O スレッドがあるため、すべての要求で 1 つの非同期操作をキューに入れることができます。これは文字通り数百回の非同期操作であり、パフォーマンスが大幅に低下することはありません (I/O サブシステムが維持できると仮定します)。それはあなたが必要とする以上のものです。
非同期デリゲートはこのようには機能しないことに注意してくださいThreadPool.QueueUserWorkItem。これを実行できるのは、.NET Framework ライブラリ クラスの組み込み非同期メソッドだけです。自分で行うこともできますが、複雑で少し危険であり、おそらくこの議論の範囲を超えています.
私の意見では、この質問に対する最良の答えは、 ASP.NET でまたはバックグラウンドインスタンスを使用しないことThreadPool Threadです。これは、Windows フォーム アプリケーションでスレッドをスピンアップするようなものではありません。この場合、UI の応答性を維持するためにスレッドを実行し、その効率性を気にする必要はありません。ASP.NET では、あなたの懸念はスループットであり、これらすべてのワーカー スレッドでコンテキストを切り替えると、を使用するかどうかに関係なく、スループットが完全に失わThreadPoolれます。
ASP.NET でスレッド コードを記述している場合は、既存の非同期メソッドを使用するように書き直すことができるかどうかを検討してください。それができない場合は、そのコードが本当に本当に必要かどうかを検討してください。バックグラウンドスレッドで実行する。ほとんどの場合、純利益を得るために複雑さを追加することになるでしょう。