C# 读取数据的多线程程序中的NullReference异常
在我的C#win表单项目中,我通过web服务读取了一些数据。这需要一些时间,所以我有这样一个线索来阅读:C# 读取数据的多线程程序中的NullReference异常,c#,multithreading,C#,Multithreading,在我的C#win表单项目中,我通过web服务读取了一些数据。这需要一些时间,所以我有这样一个线索来阅读: System.Threading.ThreadPool.QueueUserWorkItem((o) => { SMSCenter_RecievedMessages = (new SMSCenterGetMessages()).getMessages()); this.BeginInvoke(new Action(() => { if (S
System.Threading.ThreadPool.QueueUserWorkItem((o) =>
{
SMSCenter_RecievedMessages = (new SMSCenterGetMessages()).getMessages());
this.BeginInvoke(new Action(() =>
{
if (SMSCenter_RecievedMessages != null && SMSCenter_RecievedMessages.Length != 0)
{
// some code
}
}));
});
运行2天后,我遇到以下异常:
Null Reference Exception was unhandled : Object Reference Not set to an instance of an object.
在创建一个新的of对象之前,是否有可能使用了getMessage()
函数?因为我是用线做的。这个代码有什么问题
感谢您的帮助?导致错误的一个可能原因是,
SMSCenter\u receivedMessages
可能被声明为类字段。如果您的代码片段可以连续执行多次(例如,从单击事件处理程序执行),那么这可能会导致争用情况
假设事件处理程序导致代码段开始执行。后台线程使用非空值填充SMSCenter\u receivedMessages
,并将控件分派给UI线程。UI线程计算SMSCenter\u receivedMessages!=空
到真
同时,另一个事件处理程序导致代码段再次开始执行(并发执行)。这次,getMessages()
返回null
;这被分配到相同的SMSCenter\u receivedMessages
字段,并覆盖上一个值
同时,UI线程继续执行,并尝试评估
SMSCenter\u receivedMessages.Length!=0
。由于该字段现在已设置为null
,因此会出现NullReferenceException
。在哪一行获得异常?因为我在你当前的代码中找不到空引用的可能性@RohitPrakash我在SMSCenter_receivedMessages=(新的SMSCenterGetMessages()).getMessages()中得到了它;这将占用很少的时间。在这种情况下,当然,此时没有创建SMSCenterGetMessages对象。尝试使用并行堆栈来找出确切的情况。@RohitPrakash为什么new
不实例化一个新对象并将结果改为null
?@zerkms,Douglous已经解释了这一切。OP说SMSCenter\u receivedMessages=(new-SMSCenterGetMessages()).getMessages()
是导致空引用异常的行。@zerkms:在原始问题发布后,在注释中说明了澄清。在没有更多信息的情况下,SMSCenter\u receivedMessages
字段上的竞态条件仍然是最有可能的解释。我同意对于原始问题,它将是最可能的解释(如果我们忽略最后几行,其中OP也明确地指getMessages()
),但OP表示,失败的是(新的smscenetergetmessages()).getMessages())
表达式。我个人不相信这一点,但我们有我们所拥有的:-)谢谢你的好主意,但我在整个代码中使用了Lock(),我认为它解决了这个竞争条件。但是未处理的异常仍然正确。@Elahe:我建议将SMSCenter\u receivedMessages
改为局部变量,这样代码的不同执行就不会相互冲突。如果您不在其他地方使用该字段,那么这就足够了。如果您确实在其他地方使用该字段,则需要对所有使用应用锁,这可能会导致UI冻结或死锁。