2

我在將值添加到泛型字典(WinRT C#)時收到IndexOutOfRange異常。下面是我的代碼和堆棧跟蹤異常。IndexOutOfRangeExpection發生在Dictionary.Add方法

代碼:

if (!data.TryGetValue(index, out cells)) 
{ 
    cells = new CellCollection(); 
    data.Add(index, cells); 
} 

堆棧跟蹤:

在System.Collections.Generic.Dictionary 2.Insert(TKey key, TValue value, Boolean add) at System.Collections.Generic.Dictionary 2.增加(TKEY的關鍵,TValue值)

我不會」預計在添加時會出現超出範圍的異常。我的應用程序只使用單線程。 我已經添加值字典並從字典中刪除它使用GC.Collect()如果不需要。然後根據需要添加值。

任何人都可以提出任何建議來解決此異常?

+2

我想你正在訪問一個字典在多個線程沒有適當的同步這是不安全的。你是?編輯:我看到你提到的問題*我的應用程序只使用單線程*但確保你交叉檢查,看看字典是否滑到另一個線程。 – 2014-11-05 08:31:38

+0

如果這不是一個併發問題(或者如果您決定需要幫助解決這個問題),您將不得不發佈一個更好的問題,並提供一個完整但簡潔的代碼示例。到目前爲止,這裏的信息很少。有關發佈良好代碼示例的更多信息,請參閱http://stackoverflow.com/help/mcve。 – 2014-11-05 08:34:27

+0

我同意這聽起來像你有多個線程,如'Parallel.ForEach'的'.AsParallel()'或什麼的。但是,我們可以看到'TKey',即'index'的類型是什麼? – 2014-11-05 08:35:55

回答

4

在致電Dictionary<,>.Add期間,有時需要分配新的背襯陣列,因爲Count超過了Dictionary<,>的當前容量。分配新的託管對象(新數組)時,垃圾回收器可能會設置。您的應用程序「暫停」併發生垃圾回收。然後,垃圾收集後,控制將從您在Add方法中的位置恢復,並且新的後備陣列將填入舊數據。

但是,根據您對以上問題的評論,您有終結者。必須存在一個不相關的對象(可能是同一類的另一個實例),正在被定稿。它似乎持有對相同的Dictionary<,>的參考。在最終確定過程中,您的析構函數代碼將更改Dictionary<,>的狀態。然後,當主線程在垃圾收集之後恢復控制時,Dictionary<,>的狀態已更改,但我們正在向該Dictionary<,>添加一個新元素的過程中。

吸取的教訓是:不要編寫析構函數(終結器)。如果您仍然這樣做,請不要更改(可以)從別處引用的管理對象的狀態(即從不會收集的「活」對象)。

馬修沃森對你的問題發表了評論。

相關問題