多个状态对象到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
和callback
的上下文来工作。这通常能完成任务。然而,您必须必须理解捕获上下文的作用域规则,并且知道socket
是否引用迭代变量还是迭代之间共享的变量。对我来说,因为那个原因,不值得在这里冒险。
但存在其他机制:
-
可以将一个显式状态对象in作为最后一个参数传递给
BeginConnect
,并作为r.AsyncState
访问;这允许您重复使用单个委托实例来避免分配,但是您仍然需要某种元组来包含套接字和回调 -
您可以使用
ConnectAsync
;这在重用委托和拥有状态对象(这次称为UserToken
)方面具有相同的优势,但您不需要打包套接字,因为它在事件处理程序中暴露为ConnectSocket
-但它需要SocketAsyncEventArgs
实例,因此在分配方面它不会比BeginConnect
获得太多,但它确实意味着您正在使用最新的(也是最有效的)API
是否值得更改取决于该文件的容量有多大