C# ConcurrentDictionary ContainsKey方法是否已同步?

C# ConcurrentDictionary ContainsKey方法是否已同步?,c#,multithreading,concurrentdictionary,C#,Multithreading,Concurrentdictionary,简单问题 假设我有一个ConcurrentDictionary 我使用TryAdd和ContainsKey方法 现在假设我从100个线程开始处理东西。假设当3个线程使用TryAdd方法添加新密钥时,另3个线程使用ContainsKey方法询问密钥是否存在 DoContainsKey在返回结果之前等待这3个线程添加进程吗? 或者它们没有同步,我的意思是,这3个线程中的一个可以添加我用ContainsKey方法询问的密钥,但是由于这个过程还没有完成,所以我得到的答案将是错误的 答案C#WPF.net

简单问题 假设我有一个
ConcurrentDictionary

我使用
TryAdd
ContainsKey
方法

现在假设我从100个线程开始处理东西。假设当3个线程使用
TryAdd
方法添加新密钥时,另3个线程使用
ContainsKey
方法询问密钥是否存在

Do
ContainsKey
在返回结果之前等待这3个线程添加进程吗?

或者它们没有同步,我的意思是,这3个线程中的一个可以添加我用ContainsKey方法询问的密钥,但是由于这个过程还没有完成,所以我得到的答案将是错误的

答案C#WPF.net 4.5最新版本“否”(参见Sam的评论),此外,
ContainsKey
在对ConcurrentDictionary的其他访问或方法调用中建立了No原子守卫

也就是说,以下代码被破坏

Try*
方法应该一致使用

cd.TryAdd("x", y);

如果需要通过专门的并发方法来保证进一步的同步(或原子性),那么应该建立一个更大的监视器/锁上下文。

-1:我用粗体来解释这个问题“ContainsKey
ContainsKey
是否包含一个同步调用,该调用将导致它在返回其答案之前等待对
TryAdd
的调用完成?”此问题的答案是“否”“。并发集合与使用锁定进行同步的集合非常不同;它们尽可能避免锁定,通常通过使用@280Z28进行良好观察。我已经更新了关于评论的最初措辞。另外,作为支持理由,
ContainsKey
在内部使用TryGetValue(参考)。我删除了我的-1票,但保留了注释,因为它被引用了。这里有一个更好的链接:如果您指望containsKey告诉您该密钥是否存在于以前可能删除的密钥中,那么即使TryAdd也可能失败。concurrentdictionary进入一种状态,认为密钥不存在,无论是否存在,它都不能添加相同的密钥。这似乎是可怕的破坏。@nixkuroi然而,ConcurrentDictionary的内部状态在任何时候都不会变得腐败。应检查TryAdd的结果,以确保是否添加了特定密钥;任何较大的原子上下文都必须通过锁等其他方式进行保护。)
cd.TryAdd("x", y);