800 スレッドを作成するべきではありません。
ここで一歩戻りましょう。「クライアント」から「要求」を受け取り、それらのクライアントに「応答」を送り返す「サーバー」と呼ばれるデバイスがあります。要求が郵便局から配達される紙切れであり、応答が郵便局から配達される本が入った箱であるとします。
サーバーをテストするために、800 台のクライアントをシミュレートしたいと考えています。
スレッドが人で、プロセッサーが椅子だとしましょう。人は椅子に座っている間しか仕事をすることができません。
800 のスレッドを作成することは、外に出て 800 人を雇い、それぞれにお金を払ってサーバーに手紙を送ることに相当します。しかし、椅子が 4 つしかないので、800 人が交代で椅子を使用する必要があります。
それは実生活ではばかげた解決策です。スレッドは、人間と同じように、非常に高価です。作成するスレッドの数を最小限に抑える必要があります。
では、代わりにタスク ファクトリを介して 800 のタスクを作成し、TPL にそれらを並列化させるべきでしょうか?
いいえ、あなたもそうすべきではありません。TPL には、引き出される人々 (スレッド) のプールがあり、従業員が座る椅子よりも多くの人が給与に含まれないように物事を調整しようとします。しかし、あなたの仕事は「椅子に縛られている」わけではありません - - 人々は椅子に座り、リクエストをサーバーに送信し、応答が返ってくるのを待つ間に椅子から出ます。彼らが待っている間、TPL は追加のタスクを処理するためにさらに多くの人を雇う必要があります。
Web サーバーへのアクセスは I/O バウンドです。CPU バウンドのタスクに対してのみスレッド プール タスクを作成する必要があります。
正しい解決策は、 2人を雇うことです。
1 人 (「I/O 完了スレッド」) は、メールボックスに要求をドロップし、着信パッケージをチェックするだけです。もう 1 人の「シミュレーション」担当者は、800 人のクライアントをシミュレートするための適切な「スケジュール」を考え出します。シミュレーション担当者は、スケジュールを立てて就寝します。サーバーに別のリクエストを送信する時間になると、彼女は目を覚まします。彼女が目を覚ますと、彼女は I/O 完了スレッドにこの手紙をメールボックスにドロップするように指示し、応答が来たら彼女を起こします。その後、彼女は別の要求を送信する時間になるまで、または応答が来るまでスリープ状態に戻ります。確認する必要があります。
あなたがすべきことは、(1) C# 5 のベータ版を入手し、それを使用async/await
してサーバーに要求を送信するタスクを作成し、別の要求を送信する時間になるか応答が来るまで、制御をメッセージ ループに戻します。または、C# 5 を使用したくない場合は、タスク完了ソースを作成し、適切な継続を持つタスクを設定する必要があります。
要するに、多くの並列 I/O タスクを処理する正しい方法は、それぞれが一度に非常に少量の作業を行う非常に少数のスレッドを作成することです。I/O 完了スレッドに I/O の詳細を処理させます。800 通の手紙を送ることをシミュレートするために、800 人を雇う必要はありません。2人を 雇って、1 人はメールボックスを監視し、もう 1 人は手紙を書きます。