【问题标题】:Can ConcurrentDictionary.TryAdd fail?ConcurrentDictionary.TryAdd 会失败吗?
【发布时间】:2012-07-16 09:51:31
【问题描述】:

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

【问题讨论】:

  • 就目前而言,这个问题相当模糊。 MSDN page 记录了一些原因,包括特殊原因和其他原因(如迄今为止的答案所述)。
  • 是的,MSDN 文档以其清晰和完美而著称
  • 好吧,对于其他答案来说,它似乎足够清晰和完美。
  • MSDN 可能并不完美,但我还没有使用过一种比 C#/.NET 文档记录更好的语言。对于其他语言,我发现自己常常在想,如果它更像像 MSDN,文档会好得多。
  • NET 4.0 我们有一个案例,ASP.NET Web API 应用程序偶尔会导致所有后续 TryAdd 调用失败,并出现 IndexOutOfRangeException。这发生在池中的一台服务器上,直到服务器被拉出并重置应用程序池。我们还没有找到合适的方法来解决这个问题。

标签: c# concurrentdictionary


【解决方案1】:

可以,条件如下 (from msdn):

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

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

  • 如果键不同,两个插入都可以正常工作。
  • 一个插入工作正常并返回真,另一个插入失败(无异常)并返回假。如果两个线程尝试使用相同的键插入一个项目并且基本上只有一个会赢而另一个会输,就会发生这种情况。

【讨论】:

  • 好的...所以与并发访问无关...它只是执行与标准字典相同的检查。
  • 是的,它在内部使用 CPU 旋转,允许多个并发连接。
  • 谢谢.. 我接受你的回答是最有建设性的。我们在这里调试了一个相当难以捉摸的错误,并逐行排除了可能的来源。我可以根据您的贡献排除 TryAdd(尽管在添加失败的情况下我仍会添加额外的日志记录)
  • @deveL 通常很难调试多线程应用程序。但我相信System.Collections.Concurrent 命名空间,因为它已经过广泛测试。也看看parallel nunit。我从未使用过它,但它似乎解决了并行代码单元测试的问题。如果你不使用 NUnit,应该有其他框架。
  • @parliament 再次尝试会得到相同的结果,使其毫无意义。返回 false 并不意味着“我插入项目失败”它更多的是“其他东西已经插入了项目”
【解决方案2】:

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

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

返回值 类型:System.Boolean 如果键/值对已成功添加到 ConcurrentDictionary,则为 true。 如果key已经存在,这个方法返回false。

【讨论】:

  • 嗯...这是给定的。这是唯一可能失败的情况吗?
  • @daveL - 是的,当异常发生时......请参阅 Oleksii 的回答。
  • 感谢您的帮助.. 我为您 +1 了
  • 鉴于该函数的声明意图是告诉您该项目是否已添加或已经存在,我不认为返回 false 是失败的。
【解决方案3】:

当key已经存在于字典中时会失败。

如果由于内存耗尽而无法添加该值,则会出现异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-04
    • 2019-03-27
    • 2016-08-20
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    相关资源
    最近更新 更多