线程安全字典C#

线程安全字典C#,c#,dictionary,thread-safety,C#,Dictionary,Thread Safety,我的一位同事最近表示,如果您不介意检索过时数据,多个读写线程访问c#dictionary是可以的。他的理由是,由于程序将重复读取字典中的数据,过时的数据不会成为问题 我告诉他,当你有一个writer线程时,锁定一个集合总是必要的,因为集合的内部状态会被破坏 我弄错了吗 写操作需要某种形式的锁定,这一点是正确的,尽管仅仅进行写操作并不意味着必须lock(){}对集合的每次访问 正如您所说,内置集合的非同步版本仅对读取是线程安全的。通常,ReadWriterLockSlim用于在可能发生写操作的情况

我的一位同事最近表示,如果您不介意检索过时数据,多个读写线程访问c#dictionary是可以的。他的理由是,由于程序将重复读取字典中的数据,过时的数据不会成为问题

我告诉他,当你有一个writer线程时,锁定一个集合总是必要的,因为集合的内部状态会被破坏

我弄错了吗

写操作需要某种形式的锁定,这一点是正确的,尽管仅仅进行写操作并不意味着必须
lock(){}
对集合的每次访问


正如您所说,内置集合的非同步版本仅对读取是线程安全的。通常,
ReadWriterLockSlim
用于在可能发生写操作的情况下管理并发访问,因为只要没有写操作发生,它将允许多个线程访问集合,但在写操作期间只有一个线程(写入程序)。

您是正确的,而你的同事错了:一个人只能在没有作者的情况下从多个线程访问字典

.NET 4.0添加的类完全按照其名称的含义进行操作。

来源:

只要不修改集合,词典可以同时支持多个读取器。即便如此,通过集合枚举本质上并不是线程安全的过程。在枚举与写访问争用的罕见情况下,必须在整个枚举期间锁定集合。要允许多个线程访问集合进行读写,必须实现自己的同步


有关线程安全的替代方案,请参见
ConcurrentDictionary

+1了解
ConcurrentDictionary
,尽管它不能代替实际了解发生了什么。并发集合提供的功能将许多常见的多步骤流程整合到一个管理锁定的流程中,但它们不是一刀切的替代品。@AdamRobinson你关于一刀切的评论很贴切:知道发生了什么是无可替代的。他说,每当集合检测到无效的并发访问时,就会抛出异常。然后,他可以捕获异常并重试。他说他希望最小化锁定以提高性能。是否可以捕获异常并重试?@Alvin Nope,这也行不通:问题是集合并不总是检测到并发修改。除了偶尔因索引超出范围异常而跳闸外,
TryGetValue
[]
不执行任何并发检查。它们偶尔会为错误的键返回值,而不是抛出异常,因此您不知道如何重试。@Alvin他为什么要优化它?探查器是否告诉他,在
ConcurrentDictionary
内锁定是系统的瓶颈,还是过早优化?他说,每当集合检测到无效的并发访问时,就会抛出异常。然后,他可以捕获异常并重试。他说他希望最小化锁定以提高性能。是否可以捕获异常并重试?