2010-10-22 117 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 ...好得多。