繁体   English   中英

foreach在ObservableCollection上引发NullReferenceException

[英]foreach throws NullReferenceException on ObservableCollection

我有class ElementRelation { ... } class ElementRelationCollection : System.Collections.ObjectModel.ObservableCollection<ElementRelation> { ... }class ElementRelationCollection : System.Collections.ObjectModel.ObservableCollection<ElementRelation> { ... }

我有这段代码:

ElementRelationCollection a = ...;
if (a == null)
    throw new Exception("a is null(???)"); // this exception is never thrown
try
{
    foreach (ElementRelation relation in a) // exception is thrown here
    { ... } // never thrown here
}
catch (NullReferenceException ex)
{
    string message = "Something is null here. a.Count: " + a.Count;
    IEnumerator<ElementRelation> enumerator = a.GetEnumerator();
    message += ", enumerator is " + (enumerator == null ? "null" : "not null");
    throw new Exception(message, ex);
}

我从日志中看到,此代码有时会引发异常,并显示消息“这里的东西为空。a.Count:9,枚举数不为空”。 当这种情况开始发生时,它会继续在每个页面加载上排在最前面,直到iisreset。

内部异常当然是System.NullReferenceException,它具有以下堆栈跟踪:

at MyNamespace.MyClass.MyMethod() in c:\path\MyClass.cs:line 74

其中第74行是说foreach (ElementRelation relation in a)的行foreach (ElementRelation relation in a)

为什么会引发此异常?

编辑:

该集合有时由后台线程更新。 我以为这不会导致比失败的迭代更糟糕的问题,但是事实证明整个集合已损坏。

ObservableCollection<T>类不是线程安全的。 从多个线程对其进行修改可能会破坏内部状态,以致无法修改或枚举实例。

你会随机看到的例外,如NullReferenceExceptionIndexOutOfRangeException -这是最好的可能的结果! 在其他情况下,对集合所做的更改可能会被静默删除。

您可能需要使用ReaderWriterLockSlim将您对列表的访问权包装在一个锁中,或者切换到线程安全的集合。 对于.NET 4.0, System.Collections.Concurrent命名空间具有多种可能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM