在 BlockingCollection 中搜索特定元素

Posted

技术标签:

【中文标题】在 BlockingCollection 中搜索特定元素【英文标题】:Search for a particular element in BlockingCollection 【发布时间】:2021-12-06 13:28:48 【问题描述】:

我有一个BlockingCollection

private readonly BlockingCollection<ImageKeys> myCompletedImages;

我有一个向BlockingCollection 添加项目的方法:

public void addItem(ImageKey theImagekey)

    if (this.myCompletedImages.Contains(theImagekey)) // Here it says
                                                      // I do not have "Contains"
             
        return;
    
    this.myCompletedImages.Add(theImagekey);

如何知道BlockingCollection 中是否存在特定元素?由于Contains 不存在.. 还有其他方法可以吗?

【问题讨论】:

即使你可以,这样的方法也没有用,因为它可以在你检查它是否存在并且在你添加项目本身之前添加。 System.Linq 中有一个扩展方法Contains&lt;&gt;,你甚至可以提供一个IEqualityComparer&lt;T&gt; @Hazrelle 正如 Servy 已经解释的那样,这将是无用的,因为可能会在支票和 Add 调用之间添加匹配项 @Mr.Curious 你想做什么?你为什么使用 BlockingCollection 而不是 ConcurrentDictionary?可能有更好的方法(和更好的集合)来做任何你想做的事情。您是否试图阻止向订阅者/工作人员发布重复消息? 使用线程安全队列 【参考方案1】:

搜索BlockingCollection&lt;T&gt; 以查看它是否包含特定元素,这是该类的预期用途不需要的功能,它有助于生产者-消费者场景。所以这个类没有公开一个Contains 方法作为它的公共API 的一部分。您可以利用类实现IEnumerable&lt;T&gt; 接口的事实,并使用LINQ Contains 运算符,但请记住this cautionary note 来自ConcurrentBag&lt;T&gt; 类。 AFAIK 它通常适用于所有并发集合:

ConcurrentBag&lt;T&gt; 的所有公共和受保护成员都是线程安全的,并且可以从多个线程同时使用。但是,通过ConcurrentBag&lt;T&gt; 实现的接口之一访问的成员,包括扩展方法,不能保证是线程安全的,并且可能需要由调用者同步。

(强调)

因此,只有在“战斗”结束并且BlockingCollection&lt;T&gt; 实例上的所有并发操作都结束后,您才能安全地使用 LINQ Contains 扩展方法。这可能不是你想要的。在这种情况下,BlockingCollection&lt;T&gt; 可能不是您要解决的任何问题的正确工具。

【讨论】:

以上是关于在 BlockingCollection 中搜索特定元素的主要内容,如果未能解决你的问题,请参考以下文章

在 ArrayList 中搜索特定对象

如何在子目录中搜索特定文件?

spring-data-elasticsearch 在多个索引中搜索特定字段

如何在jtree中搜索特定节点并使该节点展开。?

如何在 DataTable 中搜索特定记录?

如何在Lucene中搜索特定范围内的词