2012-11-08 75 views
2

我对Async方法实现的功能有点困惑。在查找如何让服务器接受多个连接时,我遇到了它。在查找Aync在C#中完全实现的功能时,会发生什么让我困惑的是,从我可以告诉它的不是它自己的线程。但是,它也可以让你避免锁定和拖延。举例来说,如果我有以下几点:了解C#中的异步(套接字)

ConnectionManager() 
    { 
     listener = new TcpListener(port); 
     listener.BeginAcceptSocket(new AsyncCallback(acceptConnection), listener); 
    } 

    public void acceptConnection(IAsyncResult ar) 
    { 
     //Do stuff 
    } 

这是否意味着,一旦它找到一个连接,它执行“acceptConnection”的功能,但随后继续通过调用函数来执行? (在这种情况下超出范围)。这如何让我创建一个服务器应用程序,可以接受多个客户端?即使我之前使用线程来管理服务器/客户端交互,我对这个概念还是比较陌生的。如果我有点模糊,请告诉我。我在MSDN上查找了多个示例,但仍然有点困惑。提前谢谢!

回答

3

尽快找到一个连接,它执行 “acceptConnection” 功能

然后继续通过调用函数来执行?

什么是异步方式实现

如果使用得当,它可以处理/高得多的请求数量第二用更少的资源。

想象一下,您正在创建一个服务器,该服务器应该接受10个TCP端口上的连接。

与封闭API,你必须创建10个线程刚刚接受插座。线程是昂贵的系统资源,例如每个线程都有自己的堆栈,并且线程之间的切换需要相当长的时间。如果客户端连接到某个套接字,则操作系统将不得不唤醒相应的线程。

使用异步API,您发布了10个异步请求。当客户端连接时,您的acceptConnection方法将由CLR线程池中的线程调用。

还有一件事。

如果要在等待异步I/O操作完成后继续执行调用者函数,则应考虑新的C#的async/await语法,它允许您这样做。该功能可用作Visual Studio 2010的独立库“Async CTP”,并包含在Visual Studio 2012中。

+0

我不认为推荐Async CTP是一个好主意,那只是预览代码。 – svick

+0

@svick,它工作的很好,而且自SP1刷新以来,它有一个上线许可证,所以它不是“只是预览代码”。 – Soonts

+0

我在Windows 8应用程序中实现HTTP客户端的东西时看到过这段代码。然而,这些调用的大多数示例代码都等待着哪些强制您等待该函数超出范围或返回某些内容,然后再继续。 –

2

我不自称是一个C#或插座大师,但是从我了解你上面已经有了将接受第一个连接,然后没有更多的代码。您需要建立另一个BeginAccept。

喜欢的东西:除了异步连接

因此,通过使用异步
TcpListener listener = null; 

ConnectionManager() 
{ 
    listener = new TcpListener(port); 
    listener.BeginAcceptSocket(new AsyncCallback(acceptConnection), listener); 
} 

public void acceptConnection(IAsyncResult ar) 
{ 
    // Create async receive data code.. 

    // Get ready for a new connection 
    listener.BeginAcceptSocket(new AsyncCallback(acceptConnection), listener); 

} 

接收数据时,接受连接很快完成,并建立侦听新的连接。我想你也可以重新排序。

对于直插座连接(不的TcpListener),这是我用什么:

(connectedClient是我自己的类,它处理接收&发射功能,包含有关连接的其他信息)。

int Port = 7777; // or whatever port you want to listen on 
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, port); 
listenSocket = new Socket(AddressFamily.InterNetwork, 
      SocketType.Stream, ProtocolType.Tcp); 

listenSocket.Bind(ipLocal); 

// create the call back for any client connections... 
     listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null); 

private void OnClientConnection(IAsyncResult asyn) 
    { 
     if (socketClosed) 
     { 
      return; 
     } 

     try 
     { 
      Socket clientSocket = listenSocket.EndAccept(asyn); 

      ConnectedClient connectedClient = new ConnectedClient(clientSocket, this); 

      connectedClient.MessageReceived += OnMessageReceived; 
      connectedClient.Disconnected += OnDisconnection; 
      connectedClient.MessageSent += OnMessageSent; 

      connectedClient.StartListening(); 

      // create the call back for any client connections... 
      listenSocket.BeginAccept(new AsyncCallback(OnClientConnection), null); 

     } 
     catch (ObjectDisposedException excpt) 
     { 
      // Deal with this, your code goes here 

     } 
     catch (Exception excpt) 
     { 
      // Deal with this, your code goes here 
     } 

    } 

我希望这回答了您要找的内容?

+0

我喜欢你如何为连接使用事件处理。我可能会遵循这种模式:)。这非常有帮助,谢谢! –