Socket.End 方法不會擲回 ObjectDisposedException
System.Net.Sockets.Socket.End*
方法 (例如,EndSend) 在通訊端關閉後擲回 SocketException,而不是 ObjectDisposedException。
先前的行為
之前,受影響的方法會針對關閉的通訊端擲回 ObjectDisposedException。
新的行為
從 .NET 7 開始,受影響的方法會針對關閉的通訊端擲回 SocketException,並將 SocketErrorCode 設為 SocketError.OperationAborted。
導入的版本
.NET 7
中斷性變更的類型
這項變更會影響二進位相容性。
變更原因
非同步程式設計模型 (APM) API 是名為 Begin*
和 End*
的 API。 從 .NET 6 開始,這些舊版 API 由以 Task
為基礎的實作支援,作為合併和簡化 Socket
程式碼基底的一部分。 不幸的是,使用 6.0 實作,TaskScheduler.UnobservedTaskException 上有時會引發非預期的事件。 即使已正確使用 API,也會發生這種情況,這表示呼叫程式碼一律會叫用 End*
方法,包括通訊端已關閉時。
已進行要擲回 SocketException 的變更,以確保在這種情況下不會洩漏任何未觀察到的例外狀況。
建議的動作
如果您的程式碼從任何 Socket.End*
方法攔截 ObjectDisposedException,請將其變更為攔截 SocketException 並參考 SocketException.SocketErrorCode 以查詢基本原因。
注意
APM 程式碼應一律確保在對應的 Begin*
方法之後叫用 End*
方法,即使通訊端已關閉也一樣。
受影響的 API
- System.Net.Sockets.Socket.EndConnect(IAsyncResult)
- System.Net.Sockets.Socket.EndDisconnect(IAsyncResult)
- System.Net.Sockets.Socket.EndSend
- System.Net.Sockets.Socket.EndSendFile(IAsyncResult)
- System.Net.Sockets.Socket.EndSendTo(IAsyncResult)
- System.Net.Sockets.Socket.EndReceive
- System.Net.Sockets.Socket.EndAccept