是否有可能从ListBox.Items属性获取空引用错误?

时间:2009-09-21 19:59:54

标签: .net winforms listbox nullreferenceexception

编辑11-20-2009 :这个问题已经发布了很久以前,但问题刚刚在今天早上再次出现;所以我希望其他人可以提供一些见解(虽然提供的答案已经有所帮助)。

在生产环境中的蓝色月亮中,我们从引用NullReferenceException控件的Items属性获得ListBox。我在下面提供了一些示例代码。

相关ListBox的父表单包含一个名为Queue<string>的私有QueuedMessages。此队列接收有关事件的新消息。在每500毫秒关闭的计时器上,执行以下方法:

void DisplayQueuedMessages() {
    lock (QueuedMessages) {
        while (QueuedMessages.Count > 0) {
            string msg = QueuedMessages.Dequeue();
            this.lbxMessages.Items.Insert(0, msg); // NullReferenceException
            if (this.lbxMessages.Items.Count > MAX_LBX_ITEMS) {
                this.lbxMessages.Items.RemoveAt(Me.lbxMessages.Items.Length - 1);
            }
        }
    }
}

同样,正如我所提到的,这只会很少引发NullReferenceException 非常。在使用该应用程序的几个月内,它发生了三到四次。

此外,几次发生这种情况,似乎ListBox.Items属性或ListBox本身神秘地消失了:所有后续方法都将项目添加到ListBox抛出异常。恢复的唯一方法是关闭应用程序并重新启动它。

不幸的是,在其他一百万件事情上经常分心,我从来没有在插入之前添加日志记录。我现在已经添加了日志记录,但在我们再次看到此问题之前可能需要一个月或更长时间。与此同时,还有更多想法吗?有什么可能的解释?

我想我真正的问题是:有没有其他人见过这种情况 - 访问{em>做了的ListBox并突然获得NullReferenceException - 你是否能够弄清楚为什么/如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

深入研究所有代码,很可能Me.ListBox1为空。

我曾经在一个由第三方构建的应用程序上工作,这样的代码只在特定情况下调用,并在asp.net呈现代码期间导致异常......

void ClearItems()
{
   SomeField.Text = "";
   ...
   AnotherField = null; 
   ...
}

另外注意其他故障中的堆栈跟踪,如果它在控件的方法内部爆炸,则会比在代码中爆炸时更加不同。

答案 1 :(得分:1)

你有多确定Me.ListBox1没有变为空?那是我的第一次猜测。

答案 2 :(得分:1)

首先,设置条件断点并尝试查找和/或编写一些保护代码。我会在代码前添加类似tis的内容:

System.Diagnostics.Debug.Assert(Me.ListBox1 != null);
System.Diagnostics.Debug.Assert(Me.ListBox1.Items != null);
String msg = getStatusMessage(); 
System.Diagnostics.Debug.Assert(msg != null);
Me.ListBox1.Items.Insert(0, msg);

(我猜我在这里混合使用VB和C#,但是你得到了图片。)

还要确保在SelectedIndexChanged或类似事件中实际上没有发生null异常。

但它可能确实是一个ListBox问题,请参阅this question

答案 3 :(得分:1)

原因是我今天早上发现的System.Windows.Form v2.0错误(在System.Windows.Form v4.0中已修复)。

对我来说,当我的代码在托管进程关闭时向Item添加ListBox时发生了这种情况。私有实例字段ListBox.listItemsArray为空,这会激发NullReferenceException。我不知道为什么ListBox.listItemsArray为空,但我猜它与句柄创建问题有关。

对我来说,解决方法很简单,因为try/catch足够了,因为无论如何这个过程都在关闭。您可以像我一样使用反编译反射器功能来解决问题:

enter image description here

相关问题