在 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<>
,你甚至可以提供一个IEqualityComparer<T>
@Hazrelle 正如 Servy 已经解释的那样,这将是无用的,因为可能会在支票和 Add
调用之间添加匹配项
@Mr.Curious 你想做什么?你为什么使用 BlockingCollection 而不是 ConcurrentDictionary
?可能有更好的方法(和更好的集合)来做任何你想做的事情。您是否试图阻止向订阅者/工作人员发布重复消息?
使用线程安全队列
【参考方案1】:
搜索BlockingCollection<T>
以查看它是否包含特定元素,这是该类的预期用途不需要的功能,它有助于生产者-消费者场景。所以这个类没有公开一个Contains
方法作为它的公共API 的一部分。您可以利用类实现IEnumerable<T>
接口的事实,并使用LINQ Contains
运算符,但请记住this cautionary note 来自ConcurrentBag<T>
类。 AFAIK 它通常适用于所有并发集合:
ConcurrentBag<T>
的所有公共和受保护成员都是线程安全的,并且可以从多个线程同时使用。但是,通过ConcurrentBag<T>
实现的接口之一访问的成员,包括扩展方法,不能保证是线程安全的,并且可能需要由调用者同步。
(强调)
因此,只有在“战斗”结束并且BlockingCollection<T>
实例上的所有并发操作都结束后,您才能安全地使用 LINQ Contains
扩展方法。这可能不是你想要的。在这种情况下,BlockingCollection<T>
可能不是您要解决的任何问题的正确工具。
【讨论】:
以上是关于在 BlockingCollection 中搜索特定元素的主要内容,如果未能解决你的问题,请参考以下文章