gpt4 book ai didi

c# - .NET 线程/接受 TCP 连接中导致 NullReferenceException 的原因是什么?

转载 作者:可可西里 更新时间:2023-11-01 02:31:44 24 4
gpt4 key购买 nike

在我自己的网络服务器软件中,我在服务器上的事件查看器中获取包含以下堆栈跟踪的条目:

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*)

不用说,这会导致进程崩溃,这意味着服务器宕机。

由于stacktrace中没有提到我自己的代码,我很疑惑。这是 .NET 中的错误吗?如果是这样,是否有任何已知的解决方法?或者是否有导致此特定异常的已知原因?

堆栈跟踪中提到的名称 CompletionPortCallback 让我相信它发生在服务器尝试接受传入的 TCP 连接时,因此我将在下面包含相关代码。当然,如果您认为问题出在其他地方,我很乐意包含其他代码。

BeginAccept 的调用如下所示:

_listeningSocket.BeginAccept(acceptSocket, null);

这里,_listeningSocketSystem.Net.Sockets.Socket 类型。

acceptSocket 方法如下所示。我假设注释已经足够好地解释了代码;如果没有,我很乐意在评论中澄清。由于此代码在实时服务器上以 RELEASE 模式运行,因此 #if DEBUG 当然将为 false。

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
}

最佳答案

答案既简单又令人失望。

事实证明,ArgumentNullException 确实是由我自己的代码抛出的,该代码在异步调用的回调中执行,应该是在堆栈跟踪中。我太相信堆栈跟踪了;事实上,这并没有显示在堆栈跟踪中,这让我在很长一段时间内走上了错误的轨道。

正如 C# 开发人员所知,throw; 语句(不是 throw e;)应该保持异常堆栈跟踪不变。 System.Net.FixedSizeReader.ReadCallback 通过这样的 throw; 语句捕获并重新抛出异常,但事件查看器中显示的堆栈跟踪被截断。我只能推测这是 CLR 或事件查看器中的错误或两者之间的某种交互,导致仅显示 throw; 指令之后的堆栈跟踪部分。

当我在控制台而不是作为服务运行软件时,我应该早点想到这一点,异常的完整堆栈跟踪显示在控制台上,表明异常的真正原因是我自己的代码.

关于c# - .NET 线程/接受 TCP 连接中导致 NullReferenceException 的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18632207/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com