【问题标题】:Search for a particular element in BlockingCollection在 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?可能有更好的方法(和更好的集合)来做任何你想做的事情。您是否试图阻止向订阅者/工作人员发布重复消息?
  • 使用线程安全队列

标签: c# multithreading blockingcollection


【解决方案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; 可能不是您要解决的任何问题的正确工具。

【讨论】:

    猜你喜欢
    • 2012-02-13
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 2013-09-03
    • 1970-01-01
    • 2020-07-24
    相关资源
    最近更新 更多