2010-10-22 4 views
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 
} 

как на мой взгляд, этот код намного проще, чем в коде выше, и, если я правильно должен иметь относительно близкую производительность к вышеуказанному коду также.

ответ

3

Рассматривая два примера, я вижу очень мало различий (если вообще есть) в том, что происходит. Я бы рискнул, что ваша вторая форма (прямо для синхронного вызова) лучше, потому что она намного менее сложна и поведенческая идентичность. Если вы можете посмотреть источник для Accept, в какой-то момент (вероятно, в ОС) он будет делать то же самое, что и ваш более подробный код.

Однако ...

Очень быстрые моды на ваш старый код устраняет все блокировки и позволяет все происходит асинхронно:

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 
} 

ммммы ... намного лучше.

Смежные вопросы