簡體   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