Socket.End 方法不引发 ObjectDisposedException

如果套接字已关闭,System.Net.Sockets.Socket.End* 方法(例如,EndSend)会引发 SocketException 而不是 ObjectDisposedException

旧行为

以前,受影响的方法针对关闭的套接字会引发 ObjectDisposedException

新行为

从 .NET 7 开始,受影响的方法针对关闭的套接字会引发 SocketException,且 SocketErrorCode 设置为 SocketError.OperationAborted

引入的版本

.NET 7

中断性变更的类型

此项更改可能会影响二进制兼容性

更改原因

异步编程模型 (APM) API 即那些名为 Begin*End* 的。 从 .NET 6 开始,这些旧版 API 通过基于 Task 的实现获得支持,这是出于统一和简化 Socket 代码库的需要。 但使用 6.0 实现时,TaskScheduler.UnobservedTaskException 上有时会引发意外事件。 即使 API 正确使用,也会发生这种情况,这意味着调用代码始终会调用 End* 方法,包括套接字已关闭时。

更改为引发 SocketException 是为了确保在这种情况下不会泄露任何未发现的异常。

如果代码从任何 Socket.End* 方法中捕获某个 ObjectDisposedException,请将其更改为捕获 SocketException 并引用 SocketException.SocketErrorCode 来调查其根本原因。

注意

即便套接字关闭,APM 代码也应始终确保在相应的 Begin* 方法之后调用 End* 方法。

受影响的 API