ConcurrentDictionary.TryAdd可以失败吗?


76

这更多是一个学术问题...但是ConcurrentDictionary.TryAdd会失败吗?如果是,在什么情况下,为什么?


1
就目前而言,这个问题非常模糊。MSDN页面记录了一些原因,包括异常和其他原因(到目前为止,已经提到了答案)。
Christian.K

15
是的,MSDN文档以其清晰和无缺陷而著称
Dave Lawrence

4
好吧,对于其他答案而言,它似乎足够清晰和完美。
Christian.K

13
MSDN可能并不完美,但是我还没有使用一种比C#/。NET更好地文档化的语言。与其他语言,多半不是,我发现自己想的文档将如何更好的是,如果它是喜欢MSDN。
Michael Richardson

2
NET 4.0我们有一种情况,其中ASP.NET Web API应用程序偶尔会因IndexIndexOfOfRangeException而使所有后续的TryAdd调用失败。这会在池中的一台服务器上发生,直到拉出服务器并重置应用程序池为止。我们尚未找到解决此问题的合适方法。
大卫·诺斯

Answers:


110

是的,可以,这是条件(来自msdn):

  • ArgumentNullException-当键为null时引用
  • OverflowException-达到最大元素数时
  • 如果具有相同键的元素已经存在,则返回false

只是重申一下,这与并发无关。如果您担心两个线程同时插入一个项目,则可能会发生以下情况:

  • 如果键不同,则两个插入都可以正常工作。
  • 一个插入工作正常并返回true,另一个插入失败(无例外)并返回false。如果两个线程试图插入具有相同键的项,并且基本上只有一个会赢而另一个会输,则会发生这种情况。

4
好的...所以与并发访问无关。.它只是执行与标准字典相同的检查。
戴夫·劳伦斯

1
是的,它在内部使用CPU自旋,从而允许多个并发连接。
oleksii

谢谢..我接受你的回答是最有建设性的。我们正在调试一个难以捉摸的错误,并逐行排除可能的来源。我可以根据您的贡献排除TryAdd(尽管在添加失败的情况下我仍然会添加额外的日志记录)
Dave Lawrence

2
@deveL通常很难调试多线程应用程序。但是我相信System.Collections.Concurrent命名空间,因为它已经过广泛的测试。还可以看一下并行nunit。我从未使用过它,但是它似乎解决了并行代码单元测试的问题。如果您不使用NUnit,则应该有其他框架。
oleksii

1
@议会再次尝试将产生相同的结果,使其毫无意义。返回false并不意味着“我无法插入该项目”,而是“已经有其他东西插入了该项目”
Jim Wolff

8

当然可以。如果密钥已经存在,则该方法将返回false。

参考:http : //msdn.microsoft.com/en-us/library/dd267291.aspx

返回值类型:System Boolean如果成功将键/值对添加到ConcurrentDictionary,则为true。如果密钥已经存在,则此方法返回false。


好吧...这是给定的。那是唯一可能失败的情况吗?
戴夫·劳伦斯

@daveL-是的,当发生异常时...请参见Oleksii的答案。
克里斯·盖斯勒

感谢您的帮助。.我为您+1
Dave Lawrence

1
鉴于函数的既定意图是告诉您该项目是已添加还是已经存在,我认为返回false不会失败。
Niall Connaughton 2015年

2

当密钥已经存在于字典中时,它将失败。

如果由于内存用完而无法添加该值,则会获得异常。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.