![](/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.