ここでの他の答えは最も重要なポイントを省いているようです:
低負荷のサイトでCPUを集中的に使用する操作を並列化して高速に実行しない限り、ワーカースレッドを使用してもまったく意味がありません。
これは、によって作成された空きスレッドと、リクエストに応答するのnew Thread(...)
ワーカースレッドの両方ThreadPool
にQueueUserWorkItem
当てはまります。
はい、そうです。あまりにも多くの作業項目をキューに入れることThreadPool
により、ASP.NETプロセスでが不足する可能性があります。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
、など。
これらのメソッドはを使用しますがThreadPool
、ASP.NET要求に干渉しない IOCPを使用します。これらは、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でスレッドコードを作成している場合は、既存の非同期メソッドを使用するようにコードを書き直すことができるかどうかを検討し、それができない場合は、本当に本当にコードが必要かどうかを検討してください。バックグラウンドスレッドで実行します。ほとんどの場合、複雑さを追加して正味のメリットは得られないでしょう。