在我自己的网络服务器软件中,我在服务器上的事件查看器中获取条目,其中包含以下堆栈跟踪:
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.ArgumentNullException
Stack:
at System.Net.FixedSizeReader.ReadCallback(System.IAsyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Net.ContextAwareResult.Complete(IntPtr)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
不用说,这会使进程崩溃,这意味着服务器宕机。
由于没有一个堆栈跟踪提到我自己的代码,我很困惑。这是 .NET 中的错误吗?如果是这样,是否有任何已知的解决方法?或者这个特定异常是否存在已知原因?
堆栈跟踪中提到的名称CompletionPortCallback
让我相信它发生在服务器尝试接受传入的 TCP 连接时,因此我将在下面包含相关代码。当然,如果您认为问题出在其他地方,我很乐意包含其他代码。
调用BeginAccept
看起来像这样:
_listeningSocket.BeginAccept(acceptSocket, null);
在这里,_listeningSocket
是类型System.Net.Sockets.Socket
。
该acceptSocket
方法如下所示。我将假设注释对代码的解释足够好;如果没有,我很乐意在评论中澄清。由于此代码在实时服务器上以 RELEASE 模式运行,因此#if DEBUG
当然是错误的。
private void acceptSocket(IAsyncResult result)
{
#if DEBUG
// Workaround for bug in .NET 4.0 and 4.5:
// https://connect.microsoft.com/VisualStudio/feedback/details/535917
new Thread(() =>
#endif
{
// Ensure that this callback is really due to a new connection (might be due to listening socket closure)
if (!IsListening)
return;
// Get the socket
Socket socket = null;
try { socket = _listeningSocket.EndAccept(result); }
catch (SocketException) { } // can happen if the remote party has closed the socket while it was waiting for us to accept
catch (ObjectDisposedException) { }
catch (NullReferenceException) { if (_listeningSocket != null) throw; } // can happen if StopListening is called at precisely the "wrong" time
// Schedule the next socket accept
if (_listeningSocket != null)
try { _listeningSocket.BeginAccept(acceptSocket, null); }
catch (NullReferenceException) { if (_listeningSocket != null) throw; } // can happen if StopListening is called at precisely the "wrong" time
// Handle this connection
if (socket != null)
HandleConnection(socket);
}
#if DEBUG
).Start();
#endif
}