2010-10-22 115 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的源碼,那麼在某些時候(可能在OS中)它會和你的更詳細的代碼一樣。

但是......

一個非常快速的MOD您的舊代碼,消除了所有的阻擋,並讓一切發生異步:

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 
} 

MMMM ...好得多。