C# 字典与并发字典

C# 字典与并发字典,c#,asp.net,dictionary,concurrentdictionary,C#,Asp.net,Dictionary,Concurrentdictionary,我正试图理解何时使用Dictionary vs ConcurrentDictionary,因为我对字典所做的一项更改存在一个问题 我有这本字典 private static Dictionary<string, Side> _strategySides = null; 这段代码很好,已经在所有环境中运行了一段时间。当我加上 _strategySides.Add("Diagonal", Side.Diagonal); 此代码开始中断,但字典上出现异常“索引超出了数组的边界”。然后,

我正试图理解何时使用Dictionary vs ConcurrentDictionary,因为我对字典所做的一项更改存在一个问题

我有这本字典

private static Dictionary<string, Side> _strategySides = null;
这段代码很好,已经在所有环境中运行了一段时间。当我加上

_strategySides.Add("Diagonal", Side.Diagonal);
此代码开始中断,但字典上出现异常“索引超出了数组的边界”。然后,我进入了ConcurrentDictionary的概念及其用途,在我的案例中,我需要选择ConcurrentDictionary而不是Dictionary,因为它是一个多线程应用程序


所以我要问各位大师的问题是,为什么这些天它都没有抛出一个异常,而这个异常是从我在字典中添加内容开始的。对此有任何了解将不胜感激

正如您所提到的,您有多线程应用程序。字典不是线程安全的,在代码中的某个地方,当向字典添加项时,您正在同时阅读字典->
IndexOutOfboundsException

这在以下章节中提到:

一本词典可以同时支持多个读者,只要 集合未被修改。即使如此,通过集合枚举 本质上不是线程安全过程。在罕见的情况下 枚举与写访问冲突时,集合必须为 在整个枚举过程中锁定。若要允许收集,请执行以下操作: 被多个线程访问以进行读写,您必须 实现您自己的同步。有关线程安全的替代方案,请参见 并行词典


查看此问题的答案:

似乎在字典上接收此错误是线程安全冲突的特定原因。链接的答案提供了两种处理此问题的方法,一种是concurrentdictionary

如果让我猜一下为什么以前没有发生过:您正在为静态对象的构造函数中添加条目,这意味着只有一个writer,还没有reader


您的新条目可能正在构造函数之外添加?另一个线程在尝试写入时可能正在读取,这是不允许的。

字典
不是线程安全的,如果在从多个线程访问时修改它,可能会发生各种奇怪的事情,包括看起来“工作”。。。直到它没有。或者用锁保护它,或者使用专门为多线程使用而设计的数据结构(即
concurrentdirectionary

那么,它为什么“起作用”——这很难确定,但我打赌要么根本看不到问题(即内部字典状态已损坏,但由于您的使用模式,您没有注意到),要么只是在执行计时上“幸运”(例如,您可能无意中“同步”)线程(通过调试器)


关键是:不管它是什么,你都不能依赖它!你必须做“正确的事情”,即使“错误的事情”看起来“有效”。这就是多线程编程的本质。

如果您尝试
\u strategySides[“Diagonal”]=Side.Diagonal相反,它是如何工作的你初始化对象的策略方面,在它第一次使用之前,我在构造函数中添加新的条目,其他条目正在被添加,这就是为什么我很有兴趣知道“为什么现在”?@Ram如果只在静态对象的构造函数中进行写入,则无需将所有内容重写到concurrentdictionary。静态的本质是只有一个。检查您的初始定义“private static Dictionary _strategySides=null”;您可能只想在那里新建字典,因此它在这个定义和填充它的构造函数之间不“存在”。object=null仍然是可访问的对象。
_strategySides.Add("Diagonal", Side.Diagonal);