1

同じサーバー上で同期ソケット呼び出しと非同期ソケット呼び出しを組み合わせることは悪い習慣と見なされますか? 例 (msdn から変更):

// Initalize everything up here

while (true) {
     // Set the event to nonsignaled state.
     allDone.Reset();  //allDone is a manual reset event

     // Start an asynchronous socket to listen for connections.
     Console.WriteLine("Waiting for a connection...");
     listener.BeginAccept( 
     new AsyncCallback(AcceptCallback), listener);

      // Wait until a connection is made before continuing.
      allDone.WaitOne();
}

public static void AcceptCallback(IAsyncResult ar) {
    // Signal the main thread to continue.
    allDone.Set();

    // Handle the newly connected socket here, in my case have it
    // start receiving data asynchronously
}

この場合、次の接続をリッスンする前に各接続が確立されるまで待機しているため、これはほとんどブロッキング コールのように見えます。クライアントの最初の処理は別のスレッドで行われるため、少し高速になるはずですが、理論的にはオーバーヘッドは比較的小さいはずです。

これを考えると、次のようなことをするのは悪い習慣と見なされますか?

while (true) {
     // Start listening for new socket connections
     Socket client = listener.Accept(); // Blocking call


    // Handle the newly connected socket here, in my case have it
    // start receiving data asynchronously
}

私の考えでは、このコードは上記のコードよりもはるかに単純であり、私が正しければ、上記のコードに比較的近いパフォーマンスも得られるはずです。

4

1 に答える 1

3

あなたの2つの例を見ると、何が起こっているのかにほとんど違いがありません(もしあったとしても)。2 番目の形式 (同期呼び出しに直行) の方がはるかに複雑でなく、動作も同じであるため、より優れていると思います。Accept のソースを見ることができれば、ある時点 (おそらく OS 内) で、より冗長なコードとほとんど同じことを行うことになります。

でも...

古いコードを非常に簡単に変更すると、すべてのブロックがなくなり、すべてが非同期で発生します。

void Accept()
{
    Console.WriteLine("Waiting for a connection...");
    listener.BeginAccept(AcceptCallback, listener);
}
public static void AcceptCallback(IAsyncResult ar) {
            var listener = (Socket)ar.AsyncState;
            //Always call End async method or there will be a memory leak. (HRM)                
            listener.EndAccept(ar); 
    Accept();

    //bla
}

うーん...はるかに良い。

于 2010-10-22T22:29:27.957 に答える