あなたの質問に答えるには、それは両方です。それらのスレッドで実行されているスレッドとクラスがあります。WCF、async、socketsなどを使用するかどうかに関係なく、スレッドでオブジェクトを実行します(または、asyncのようにスレッドプールをシャッフルします)。WCFを使用すると、同時実行モデルを構成できます。ackやその他の確認応答を待つ必要がある場合は、他のリクエストをブロックしないように、複数のスレッドに設定するのが最適です。
作成者にリンクした例AsyncCallback
では、ソケットにデータがあることを通知するメカニズムとして使用しています。しかし、MSDNから次のことがわかります。
AsyncCallbackデリゲートを使用して、非同期操作の結果を別のスレッドで処理します
したがって、小規模なアプリでもまったく違いはありません。このように非同期を使用すると、スレッドごとにスタックスペースを割り当てないようにすることができます。大規模なアプリケーションを実行する場合は、これが問題になります。しかし、小さなアプリの場合、それは複雑さを増すだけだと思います。C#4.5+とF#は非同期でよりクリーンな仕事をするので、そのようなものを使用できるのであれば、多分それを選んでください。
これを自分のやり方で行うと、ソケット管理を担当する単一のスレッドができます。それは座って、新しい接続を受け入れます。リクエストを受け取ると、そのソケットを新しい専用スレッドに渡します。新しい専用スレッドは、そのソケットに配置され、そこから読み取ります。このスレッドはクライアント接続です。ソケットクライアントの読み取り値を、必要な低レベルのioを実行し、要求のルーターとして機能できる基本クラスにカプセル化するのが好きです。つまり、リクエストXYZを受け取ったら、ABCをリクエストします。イベントをディスパッチして、他の場所でそれらのイベントをサブスクライブさせることもできます(非同期の例のように)。これで、クライアントロジックをソケット読み取りロジックから切り離しました。
WCFを使用して作業を行う場合、ソケットやその他の処理は必要ありませんが、呼び出しはマルチスレッドであり、該当する場合はアプリケーションを適切に同期することに注意してください。
60のクライアントの場合、自分に最適なものを選択する必要があると思います。WCFはセットアップと操作が簡単です。私はそれを使用しますが、ソケットも問題ありません。実行中のスレッドの数が気になる場合は、気にしないでください。実行中のスレッドが多すぎるのは悪いことですが、IOを待機している間、ほとんどのスレッドは実際にはブロックされます。待機状態にあるスレッドは、OSによってスケジュールされておらず、実際には重要ではありません。言うまでもなく、待機は内部でio完了ポートを使用している可能性が高いため、待機のオーバーヘッドは、あなたのような小さなアプリケーションではほとんど無視できます。
結局、私は、書き、維持し、拡張するのが最も簡単なものなら何でもやります。