c# - ObjectDisposedException SslStream 和 TcpClient
问题描述
我正在使用带有 SslStream 的 TcpClient。一般来说,一切正常,但我们偶尔会收到崩溃日志。它似乎来自不稳定的网络连接,尽管尝试创建“意外情况”,但很遗憾我无法在本地重现它:
- 使用 Fiddler 复制非常慢的网络连接
- 在发送数据时杀死服务器应用程序
- 断开网络电缆
情况是这样的:
我这样称呼 BeginRead:
_tcpClientStream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, pfnCallBack, null);
然后 EndRead 被这样调用:
iRx = _tcpClientStream.EndRead(asyn);
唯一使用 iRx 的地方是将接收到的数据复制到一个新数组中:
var bytes = new byte[iRx];
Array.Copy(receiveBuffer, bytes, iRx);
在 OnDataReceived 回调函数中,我在 SslStream 上调用 EndRead,它会抛出一个异常,然后处理:
Error in OnDataReceived System.IO.IOException: The read operation failed, see inner exception. ---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: size
at System.Net.Sockets.NetworkStream.BeginRead(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.FixedSizeReader.StartReading()
at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
--- End of inner exception stack trace ---
at System.Net.Security._SslStream.EndRead(IAsyncResult asyncResult)
at System.Net.Security.SslStream.EndRead(IAsyncResult asyncResult)
at XXXXXXX.OnDataRecevied(IAsyncResult asyn)
通常这不是问题 - 这个异常被捕获并且 TcpClient 被关闭并重新启动以尝试重新连接。
但是,在这种情况下,会引发第二个异常,它来自 UnhandledException 错误处理程序之一:
AppDomain.CurrentDomain.UnhandledException
Current.DispatcherUnhandledException
Current.Dispatcher.UnhandledException
TaskScheduler.UnobservedTaskException
这个堆栈跟踪是这样的:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
我们对此类未处理错误的处理是向用户显示一条消息,指出存在致命错误并且软件必须关闭。
我的问题是:
有没有人以前见过这个错误并且能够重现我得到的确切的超出范围的异常?尽管我尝试重新创建问题(使用上述方法),但我无法重新创建异常,它始终是更标准的 Socket IO 异常:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult) --- End of inner exception stack trace --- at System.Net.Security._SslStream.EndRead(IAsyncResult asyncResult) at System.Net.Security.SslStream.EndRead(IAsyncResult asyncResult) at XXXXXXXXX.OnDataRecevied(IAsyncResult asyn)
有什么方法可以在我的 Socket 代码中处理这个异常,还是它总是会出现在这些 UnhandledException 事件之一中?如果是这样,处理此问题的最佳实践方法是什么?基本上我需要事件处理程序中的一些逻辑来确定如果收到此特定错误,软件不应关闭?
解决方案
推荐阅读
- excel - 动态范围的偏移功能不忽略折线图中#N/A 的单元格
- javascript - javascript-尝试添加内部html然后单击它不起作用
- c++ - 谷歌测试没有找到任何测试
- python - Opencv、Python 和 raspberrypi3
- bokeh - Jupyter Lab 构建在 jupyterlab_bokeh 上挂起
- android - Firebase 15.0.2 更新-android 单元测试失败
- wordpress - LinkedIn WordPress 插件
- python-2.7 - 如何请求从服务器获取最少的数据?
- azure - 如何在 Azure Functions 中使用仅限 Azure Blob 的存储帐户 - 尝试创建 Blob 快照
- websocket - Websocket 使用统计