C#,WinForms:ListBox.Items.Add生成一个OutOfMemoryException,为什么?
首先,我找到了exception的解决方案。 我更好奇为什么它会产生特定的例外。
在我的场景中,我正在向ListBox中添加一个POCO ,如下所示:
myListBox.Items.Add(myPOCO);
这产生了一个OutOfMemoryException
。 问题是,关闭POCO的ToString
返回null
。 我添加了一个string.IsNullOrEmpty
检查以在null时返回“安全”值并且exception消失。
为什么这会产生OutOfMemoryException
而不是其他东西(比如说NullReferenceException
)?
编辑 :项目在for循环中添加。
完整的调用堆栈(删除了公司特定的引用)如下。 有一点需要注意 – 调用它时列表框为空。
System.OutOfMemoryException was unhandled Message="List box contains too many items." Source="System.Windows.Forms" StackTrace: at System.Windows.Forms.ListBox.NativeAdd(Object item) at System.Windows.Forms.ListBox.ObjectCollection.AddInternal(Object item) at System.Windows.Forms.ListBox.ObjectCollection.Add(Object item) at
这是因为System.Windows.Forms.ListBox.NativeAdd
方法的实现方式:
private int NativeAdd(object item) { int num = (int) base.SendMessage(0x180, 0, base.GetItemText(item)); switch (num) { case -2: throw new OutOfMemoryException(); case -1: throw new OutOfMemoryException(SR.GetString("ListBoxItemOverflow")); } return num; }
GetItemText方法在返回null
的对象上使用ToString()
,因此使用null
参数发送消息,该参数又返回无效指针,并输入引发exception的第二种情况。
当底层LB_ADDSTRING
Windows API调用失败时,WinForms始终返回OutOfMemoryException
。 .NET Framework参考源中的注释解释了原因:
// On some platforms (eg Win98), the ListBox control // appears to return LB_ERR if there are a large number (>32000) // of items. It doesn't appear to set error codes appropriately, // so we'll have to assume that LB_ERR corresponds to item // overflow. // throw new OutOfMemoryException(SR.GetString(SR.ListBoxItemOverflow));