![](/img/trans.png)
[英]Foreach throws NullReferenceException on not null IEnumerable with elements
[英]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>
类不是线程安全的。 从多个线程对其进行修改可能会破坏内部状态,以致无法修改或枚举实例。
你会随机看到的例外,如NullReferenceException
和IndexOutOfRangeException
-这是最好的可能的结果! 在其他情况下,对集合所做的更改可能会被静默删除。
您可能需要使用ReaderWriterLockSlim
类将您对列表的访问权包装在一个锁中,或者切换到线程安全的集合。 对于.NET 4.0, System.Collections.Concurrent
命名空间具有多种可能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.