IndexOutOfRangeExpection 发生在 Dictionary.Add 方法上

Sel*_*amz 3 c# generics dictionary windows-runtime indexoutofrangeexception

我在向通用字典 (WinRT C#) 添加值时遇到 IndexOutOfRange 异常。下面是我的代码和异常的堆栈跟踪。

代码:

if (!data.TryGetValue(index, out cells))
{
   cells = new CellCollection();
   data.Add(index, cells);
}
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

在 System.Collections.Generic.Dictionary 2.Insert(TKey key, TValue value, Boolean add) at System.Collections.Generic.Dictionary2.Add(TKey 键,TValue 值)

我不希望在添加时发生这种超出范围的异常。我的应用程序仅使用单线程。我已将值添加到字典中,并在不需要时使用 GC.Collect() 将其从字典中删除。然后根据需要添加该值。

任何人都可以提出解决此异常的建议吗?

Jep*_*sen 5

在调用过程中,Dictionary<,>.Add有时需要分配一个新的后备数组,因为Count超出了 的当前容量Dictionary<,>。当分配新的托管对象(新数组)时,可能会设置垃圾收集器。您的应用程序将“暂停”并进行垃圾收集。然后,在收集垃圾后,控制将从方法内部的位置恢复Add,并且新的后备数组将填充旧数组中的数据。

但是,根据您对上述问题的评论,您有Finalizer。必须存在一个正在被终结的不相关的对象(可能是同一类的另一个实例)。看起来它包含对相同的引用Dictionary<,>。在终结过程中,您的析构函数代码会更改Dictionary<,>. 然后,当主线程在垃圾收集后恢复控制时, 的状态Dictionary<,>已更改,但我们正处于向该 添加一个新元素的过程中Dictionary<,>

吸取的教训是:不要编写析构函数(终结器)。如果您无论如何都这样做,请不要更改(可以)从其他地方引用的托管对象的状态(即从不会被收集的“活动”对象)。

马修·沃森在对你的问题的评论中这样说道。