3

開いている TcpClient オブジェクトがたくさん (約 1000 としましょう) ある C# プログラムを持っています。それらの接続のいずれかで何かが起こるのを待つ状態に入りたいです。

接続ごとにスレッドを起動したくありません。

何かのようなもの...

while (keepRunning)
{
     // Wait for any one connection to receive something.
     TcpClient active = WaitAnyTcpClient(collectionOfOpenTcpClients);

     // One selected connection has incomming traffic. Deal with it.
     // (If other connections have traffic during this function, the OS
     // will have to buffer the data until the loop goes round again.)
     DealWithConnection(active);
}

追加情報:
TcpClient オブジェクトは TcpListener から取得されます。
ターゲット環境は、MS .NET または Mono-on-Linux になります。
プロトコルは、接続が開いている間、長時間のアイドル状態を要求します。

4

1 に答える 1

2

あなたがやろうとしていることは、Microsoftの用語では非同期パターンと呼ばれています。全体的な考え方は、すべてのI/Oブロッキング操作を非ブロッキングに変更することです。これが行われる場合、アプリケーションは通常、マシンにあるCPUコアと同じ数のシステムスレッドを必要とします。

.Net4のタスク並列ライブラリをご覧ください。http: //msdn.microsoft.com/en-us/library/dd460717%28VS.100%29.aspx

これは、昔ながらのBegin / Callback /Context.Netパラダイムをかなり成熟したラッパーです。

アップデート:

接続から読み取った後、データをどのように処理するかを考えてください。実際には、おそらくクライアントに返信するか、データをファイルに保存する必要があります。この場合、ロジックを格納/管理し、単一のスレッド内にとどまるために、いくつかのC#インフラストラクチャが必要になります。TPLはそれを無料で提供します。その唯一の欠点は、.Net 4で導入されたため、おそらくまだMonoでは導入されていないことです。

考慮すべきもう1つのことは、接続の存続期間です。接続はどのくらいの頻度で開閉され、どのくらいの期間存続しますか?TCP接続を受け入れて切断するには、クライアントとのパケット交換が必要になるため、これは重要です(これは本質的に非同期であり、さらに、悪意のあるクライアントはACK(-nowledged)パケットをまったく返さない可能性があります)。この側面がアプリにとって重要であると思われる場合は、.Netでこれを適切に処理する方法を調査することをお勧めします。WinAPIでは、対応する関数はAcceptExとDisconnectExです。おそらく、Begin / Endメソッドを使用して.Netにラップされています。この場合は、問題ありません。それ以外の場合は、これらのWinAPI呼び出しのラッパーを作成する必要があります。

于 2011-04-04T17:14:45.823 に答える