提问人:arul 提问时间:12/27/2008 最后编辑:arul 更新时间:12/28/2008 访问量:491
奇怪的 nullreference 异常
Strange nullreference exception
问:
因此,我有这段代码来处理来自远程计算机的命令确认,有时(例如每 14 天一次)以下行会引发空引用异常:
computer.ProcessCommandAcknowledgment( commandType );
真正让我烦恼的是,我在它之前检查了一个空引用,所以我不知道发生了什么。 以下是其价值的完整方法:
public static void __CommandAck( PacketReader reader, SocketContext context )
{
string commandAck = reader.ReadString();
Type commandType = Type.GetType( commandAck );
Computer computer = context.Client as Computer;
if (computer == null)
{
Console.WriteLine("Client already disposed. Couldn't complete operation");
}
else
{
computer.ProcessCommandAcknowledgment( commandType );
}
}
有什么线索吗?
编辑:ProcessCommandAcknowledgeledgment:
public void ProcessCommandAcknowledgment( Type ackType )
{
if( m_CurrentCommand.GetType() == ackType )
{
m_CurrentCommand.Finish();
}
}
答:
是否有可能返回 null?这将导致 GetType 失败。也许您收到了一个空包?或者,字符串可能与类型不匹配,因此 commandType 在以后使用时将为 null。ReadString()
编辑:
您是否在调用时检查过不为空?m_CurrentCommand
ProcessCommandAcknowledgment
评论
根据您提供的信息,在该位置发生空引用似乎是不可能的。因此,下一个问题是“您如何知道特定行正在创建 NullReferenceException?是否正在使用调试器或堆栈跟踪信息?您是否正在检查代码的零售版本或调试版本?
如果是调试器,则各种设置组合实质上会导致调试器在不同位置报告 NullRef。这样做的主要方法是“仅我的代码”设置。
根据我的经验,我发现确定异常实际发生的行的最可靠方法是......
- 关闭 JMC
- 使用 Debug 进行编译
- 调试器 -> 设置 -> 引发 CLR 异常时中断。
- 检查调试器窗口中的 StackTrace 属性
评论
我敢打赌,你的TCP框架代码有问题(如果你有的话!
“PacketReader”可能表明您没有。因为,从技术上讲,如果你这样做,它将被称为“FrameReader”或类似的东西。
如果涉及的两台 PC 位于本地 LAN 或其他设备上,那么它可能会解释 14 天的间隔。如果您在互联网上尝试过,我敢打赌您的错误频率会更常见,尤其是在 WAN 带宽受到争议的情况下。
评论
如果您打开了优化,它可能会将您指向一个非常错误的地方,而实际发生它。
几年前,类似的事情发生在我身上。
评论
否则,可能在上下文被另一个线程设置为 null 的某个地方发生线程争用。这也可以解释这种错误的不常见性。
好吧,这真的只有几种可能性。
不知何故,当您调用该例程时,您的计算机引用被踩踏了。
调用下的某些内容引发了空指针取消引用错误,但在该行检测到该错误。
看着它,我非常怀疑堆栈正在损坏,导致您的自动系统被破坏。检查你遇到问题的子程序/方法/函数调用周围的子程序/方法/函数调用;特别是,请检查您制作成“计算机”项目的内容是否确实是您期望的类型。computer
评论
其他线程在做什么?
编辑:您提到服务器是单线程的,但另一条评论表明这部分是单线程的。如果是这种情况,您仍然可能遇到并发问题。
我认为,这里的底线是,您要么遇到多线程问题,要么遇到 CLR 错误。你可以猜到我认为哪个更有可能。
评论
计算机。过程命令确认( commandType );
您是否有调试符号可以单步执行此操作?
ProcessCommandAcknowledgement 可能会引发 null ref 异常,并冒泡。
评论