ConcurrentDictionary.TryAdd会失败吗?

85

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


1
就目前而言,这个问题相当模糊。MSDN 页面记录了一些原因,包括异常和其他原因(正如迄今为止的答案所提到的)。 - Christian.K
18
是的,MSDN文档以其清晰和无瑕疵而闻名。 - Dave Lawrence
4
好的,这段话的翻译如下:看起来其他答案已经很清晰和完美了。 - Christian.K
16
MSDN可能并非完美,但我还未使用过比C#/.NET更好文档化的语言。与其他语言相比,我常常会想如果它们的文档更像MSDN那样“多一些”,那将会更好。 - Michael Richardson
2
NET 4.0 我们遇到了一个问题,即 ASP.NET Web API 应用程序偶尔会在所有后续的 TryAdd 调用中失败,并出现 IndexOutOfRangeException。这种情况只会在池中的一个服务器上发生,直到该服务器被拉出并重置应用程序池。我们尚未找到适当的解决方法。 - David North
3个回答

124

是的,可以,以下是条件(来自MSDN):

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

再次强调,这与并发无关。如果您担心两个线程同时插入项,则可能会出现以下情况:

  • 如果键不同,则两个插入操作均正常工作。
  • 一个插入操作正常工作并返回true,另一个插入操作失败(没有异常)并返回false。如果两个线程尝试插入具有相同键的项,则基本上只有一个线程会成功,而另一个线程则会失败。

4
好的...所以与并发访问无关...它只是执行与标准字典相同的检查。 - Dave Lawrence
1
是的,它在内部使用CPU自旋技术,可以允许多个并发连接。 - oleksii
2
@deveL 调试多线程应用程序通常非常困难。但是我会信任 System.Collections.Concurrent 命名空间,因为它经过了广泛的测试。此外,可以查看 parallel nunit。虽然我从未使用过它,但它似乎解决了并行代码单元测试的问题。如果您不使用 NUnit,则应该有其他框架可供选择。 - oleksii
1
@parliament 再试一次会得到相同的结果,这样做是没有意义的。返回 false 并不意味着“我插入项目失败”,而是“其他东西已经插入了该项目”。 - Jim Wolff
1
所以如果这与并发无关,为什么ConcurrentDictionary没有标准的Add方法呢? - Stephen Holt
显示剩余2条评论

8

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

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

返回值:System.Boolean类型,如果向ConcurrentDictionary成功添加了键/值对,则返回true。 如果键已经存在,则此方法返回false。


嗯...那是必然的。它失败的唯一情况吗? - Dave Lawrence
@daveL - 是的,当异常发生时...请参考Oleksii的回答。 - Chris Gessler
谢谢你的帮助。我给你点了个赞。 - Dave Lawrence
1
考虑到该函数的声明意图是告诉你该项是否已添加或已存在,我认为返回 false 并不算是失败。 - Niall Connaughton

1

如果字典中已经存在相同的键,添加操作将会失败。

如果由于内存不足而无法添加值,则会抛出异常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接