是否有任何情况 TcpClient.Close 或 Socket.Close(0) 可能会阻止我的代码
本文关键字:Close 代码 我的 情况 任何 TcpClient 是否 Socket | 更新日期: 2023-09-27 18:21:44
由于没有指定 Close 方法是线程安全的,所以我应该从锁中调用它。我如何确定它不会阻塞我的线程?我应该禁用 LingerState 还是可以启用它?
顺便说一句,我需要同时调用TcpClient.Close和TcpClient.Client.Close吗?
根据 TcpClient.Close 的文档,调用此方法会释放实例。 快速浏览一下 ILSpy 就会发现它只是调用 Dispose
,这会调用Dispose(true)
。
此外,文档指出,调用Close
也会释放基础Socket
。
事实上,在处理Socket
之前,它调用了Shutdown(SocketShutdown.Both(。
鉴于 .NET 套接字是 Windows 套接字的包装器,则也会调用关闭函数,其文档指出:
注意:无论套接字上的SO_LINGER设置如何,关机功能都不会阻止。
但是,Socket
重载其Close
方法以接受超时参数,与TcpClient
类似,Socket.Close
方法调用Socket.Dispose(true)
,后者使用超时值来确定它是否可以阻塞。
根据 Socket.Close(int( 的文档:
如果需要在不先调用 Shutdown 的情况下调用 Close,则可以通过将 DontLinger 选项设置为 false 并指定非零超时间隔来确保发送排队等待传出传输的数据。然后,Close 将阻止,直到发送此数据或指定的超时到期。如果将 DontLinger 设置为 false 并指定零超时间隔,则 Close 将释放连接并自动丢弃传出排队的数据。
显然,TcpClient
或Socket
都没有将超时值作为可设置属性向您公开,并且默认值不是0
;因此,似乎为了避免阻塞,您必须在调用TcpClient.Close
之前自己调用Socket.Close(0)
。
请记住,Close
也可以抛出SocketException
,尽管框架设计指南建议永远不要抛出对Dispose
的调用。 也许这就是它被命名为 Close
并且TcpClient
显式实现 Dispose
方法的原因之一。