C# 将多个状态对象连接到套接字。开始*

C# 将多个状态对象连接到套接字。开始*,c#,asynchronous,C#,Asynchronous,我有这门课: class NetworkManager { public void Connect(IPAddress address, int port, Action callback) { Socket socket = new Socket(...); socket.BeginConnect(address, port, r => EndConnect(r, socket, callback), null); } priva

我有这门课:

class NetworkManager {
    public void Connect(IPAddress address, int port, Action callback) {
        Socket socket = new Socket(...);
        socket.BeginConnect(address, port, r => EndConnect(r, socket, callback), null);
    }

    private void EndConnect(IAsyncResult r, Socket socket, Action callback) {
        //End the connection and call the callback method
    }
}
这种发送多个状态对象的方法好吗

如果我把开始放在一个循环中,我还会经过正确的插座吗

Socket socket;
for(...){
    socket = new Socket(...);
    socket.BeginConnect(address, port, r => EndConnect(r, socket, callback), null);
}

我觉得应该有一种更正确的方法来做,有什么建议吗?

,通过创建一个捕获上下文来阻止
socket
回调
。通常情况下,它会完成工作。但是,必须了解捕获上下文的作用域规则,并知道
socket
是指每次迭代的变量还是指迭代之间共享的变量。就我的钱而言,因此不值得在这里冒险

但也存在其他机制:

  • 您可以将显式状态对象作为最后一个参数传入
    BeginConnect
    ,并作为
    r.AsyncState
    访问;这允许您重复使用单个委托实例来避免分配,但仍然需要某种元组来包含套接字和回调

  • 您可以使用
    ConnectAsync
    ;这在重用委托和拥有状态对象(这次称为
    UserToken
    )方面具有相同的优势,但您不需要打包套接字,因为它在事件处理程序中作为
    ConnectSocket
    公开-但它需要一个
    SocketAsyncEventArgs
    实例,因此,在分配方面,它不会比
    BeginConnect
    获得太多好处,但它确实意味着您正在使用最新(也是最有效)的API


是否值得更改取决于它的容量有多大。

谢谢,我们将了解ConnectAsync。出于某种原因,我一直在使用BeginConnect,我想是时候进行一些更改了。@Ineenth请注意
Socket.*Async
方法的用法:它返回一个
bool
;如果返回值为
false
,则它将异步执行,并且将引发事件处理程序。如果返回值为
true
则已执行同步,并且不会引发事件处理程序-您需要自己调用代码。这是为了避免堆栈跳水,特别是在“读取”代码中。显然,“连接”不太可能同步完成!