Reputation: 382
I am getting an IndexOutOfRange exception while adding values to Generic dictionary (WinRT C#). Below is my code and stack trace of exception.
Code:
if (!data.TryGetValue(index, out cells))
{
cells = new CellCollection();
data.Add(index, cells);
}
Stack trace:
at System.Collections.Generic.Dictionary
2.Insert(TKey key, TValue value, Boolean add) at System.Collections.Generic.Dictionary
2.Add(TKey key, TValue value)
I wouldn't expect this out of range exception occurs while adding. My application uses single thread only. I have add values to dictionary and remove it from dictionary using GC.Collect() if not needed. And then add the value if needed.
Can anyone give any suggestion to resolve this exception?
Upvotes: 4
Views: 5147
Reputation: 61952
During a call to Dictionary<,>.Add
it will sometimes be necessary to allocate a new backing array because the Count
exceeds the current capacity of the Dictionary<,>
. When allocating a new managed object (the new array) the garbage collector might set in. Your application is "paused" and garbage collection takes place. Then after garbage is collected, control resumes from where you were inside the Add
method, and the new backing array is filled with data from the old one.
However, based on your comments to your question above, you have finalizers. There must exist an unrelated object (maybe another instance of the same class) that is being finalized. It seems it holds a reference to the same Dictionary<,>
. During the finalization, your destructor code, you change the state of the Dictionary<,>
. Then when the main thread resumes control after the garbage collection, the state of the Dictionary<,>
has been changed, but we were in the middle of a process of adding one new element to that Dictionary<,>
.
The lesson learned is: Do not write destructors (finalizers). If you do anyway, do not change the state of managed objects that are (can be) referenced from elsewhere (i.e. from "living" objects that will not be collected).
Matthew Watson said it in a comment to your question.
Upvotes: 6