首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ConcurrentDictionary.Count >0与ConcurrentDictionary.Any()相同吗?

ConcurrentDictionary.Count >0与ConcurrentDictionary.Any()相同吗?
EN

Stack Overflow用户
提问于 2015-04-01 19:33:01
回答 3查看 2K关注 0票数 4

如果我有一个ConcurrentDictionary实例,那么我是使用Count属性还是使用LINQ的Any()是否重要?我宁愿写dict.Any()而不是dict.Count > 0,因为我认为Any()更具有描述性。

我只关心正确性,而不是性能。用例是

代码语言:javascript
复制
void process()
{
   if (concurrentDictionary.Count <= 0) // or !Any() ?
      return; // dictionary is empty, nothing to do

   // ...
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-04-01 19:57:02

IEnumerable Linq方法线程安全吗?的问题解决了这样一个事实:如果没有保护集合的特定锁,LINQ查询上的IEnumerable方法就不是线程安全的。

您可以查看ConcurrentDictionary参考代码,以了解枚举数没有提供线程安全快照。另外,ConcurrentDictionary.GetEnumerator的MSDN文档声明:

从字典返回的枚举器与读和写字典同时使用是安全的,但是它并不表示字典的即时快照。通过枚举数公开的内容可能包含在调用GetEnumerator之后对字典所做的修改。

Count属性对字典进行完全锁定,并返回一致的结果。

因此,取决于您是否希望在字典上使用锁来运行Any(),检查Count > 0可能更简单。

票数 4
EN

Stack Overflow用户

发布于 2015-04-01 19:41:06

您将不得不对它们进行基准测试,因为Any()类似于

代码语言:javascript
复制
using (IEnumerator<TSource> enumerator = source.GetEnumerator())
{
    if (enumerator.MoveNext())
    {
        return true;
    }
}

return false;

因此,它需要枚举,对于ConcurrentDictionary来说,这是一件复杂的事情,但即使是Count of ConcurrentDictionary也没有缓存,而且看起来相当复杂。

我要补充的是,Count仍然必须遍历一些内部结构(如数组中的那样),查询整个字典上的锁,而Any()将在第一个非空桶处停止。我要说的是,对于一个大字典,Count更慢,而对于一个小字典,它更快。

更正:Count在计数前对所有字典都有一个锁。它确实叫this.AcquireAllLocks()

请记住,这两种方法的结果可能会在方法返回之前被篡改,因为.并发!:)

票数 2
EN

Stack Overflow用户

发布于 2015-04-01 19:36:22

我是使用Count属性还是LINQ的Any()

不是的。它们在功能上是相同的,它们的性能差别应该很小。使用任何传达最恰当的含义的东西,只有当性能问题对整个应用程序的性能有重大影响时,才可以更改它。

Count将在调用该属性时对字典中的项进行计数。

Any将调用ConcurrentDictionary.GenEnumerator(),以查看字典中是否有任何项。根据文档,返回的枚举数将在调用GetEnumerator()后对字典进行反映和更改。

因此,从理论上讲,如果在调用Any和在Any中调用MoveNext之间添加了一个项,那么它们的计数得到不同的答案是可能的。然而,时间窗应该是如此之短,希望应该很小。

再加上谁能说哪个是对的?如果可以在添加项的同时使用AnyCount,则集合是否为空?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29399256

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档