使用.Net 4.0。我有一些代码尝试使用BeginConnect和回调打开连接。如果用户在接下来的几分钟内尝试停止编程,则尝试断开连接。那时,我设置了一个标志来指示是否需要从回调中调用EndConnect。如果该标志设置为false,我将跳过EndConnect,因为无论如何套接字都已被废弃。
此时,用户可以立即尝试再次连接。我看不到这种情况,但以防万一。现在,创建了一个新的套接字,并再次调用BeginConnect。
永远不要调用EndConnect方法可以吗?
最佳答案
在所有情况下(one [1]除外),对BeginZZZ
的调用都需要匹配的EndZZZZ
。
否则,非托管资源将被泄漏,并且很有可能ZZZZ
操作将无法正确完成-稍后可能破坏ZZZZ
的进一步使用。
套接字非常强大,可以防止滥用(IP堆栈必须处理网络故障和数据包乱序),但这并不是一个好的做法。
如果使用标志来跟踪“关闭”,最好调用EndConnect
,然后立即关闭套接字。在所有连接本身都可能失败之后,并且不需要断开连接(EndConnect
会引发SocketException
)。就像是:
mySocket.BeginConnect(address, port, ia => {
if (shuttingDown) {
try {
mySocket.EndConnect(ia);
mySocket.BeginDisconnect(false, iaa = {
try {
mySocket.EndDisconnect(iaa);
} catch (Exception) { /* Ignore */ }
}, null);
} catch (SocketException) { /* Ignore */ }
} else {
// Normal connection handling
}
}, null);
还使用异步断开连接以避免阻塞那里。
[1]在WinForms中,该异常为
Control.BeginInvoke
,其中明确记录了该异常。