多个状态对象到Socket.Begin*

本文关键字:Socket Begin 对象 状态 | 更新日期: 2023-09-27 18:10:31

我有这样一个类:

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
    }
}

这种发送多个状态对象的方法好吗?

如果我把begin放在循环中,我还会传递正确的套接字吗?

Socket socket;
for(...){
    socket = new Socket(...);
    socket.BeginConnect(address, port, r => EndConnect(r, socket, callback), null);
}
我觉得应该有一个更正确的方法来做这件事,有什么建议吗?

多个状态对象到Socket.Begin*

这将通过创建捕获socketcallback的上下文来工作。这通常能完成任务。然而,您必须必须理解捕获上下文的作用域规则,并且知道socket是否引用迭代变量还是迭代之间共享的变量。对我来说,因为那个原因,不值得在这里冒险。

但存在其他机制:

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

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

是否值得更改取决于该文件的容量有多大