使用.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,其中明确记录了该异常。

07-24 13:59