如何创建不重复的ConcurrentQueue?

时间:2011-04-30 23:12:53

标签: c# .net collections concurrency

我需要一个不允许重复的concurent集合(在BlockingCollection中用作Producer / Consumer)。 我不需要严格的元素顺序。 从另一方面,我想最小化元素“活”在集合中的最大时间。即集合不能是LIFO,理想情况下它应该是FIFO。

嗯,我会说我需要ConcurrentQueue而不允许重复,但是没有重复的ConcurrentBag也可能有用。

为什么C#不包含任何类似内容,可能有人已经创建了它?

此问题是我之前提问What type of IProducerConsumerCollection<T> to use for my task?

的结果

3 个答案:

答案 0 :(得分:3)

没有内置的.Net库将这组规则组合在一起。您有三种选择:

  1. 编写自己的集合类
  2. 使用两个集合:编写一个使用一个ConcurrentQueue的自定义类和任何自动检查重复项的基于集合的集合;已添加到Set run,如果成功,则添加到ConcurrentQueue;
  3. 时,每个添加/删除都会添加到两个集合中
  4. 使用ConcurrentQueue但迭代整个列表检查重复
  5. 最后两个不是非常有效(一个有内存,另一个有CPU,I / O,锁定)并且由于需要显式锁定而更加混乱,但是可以完成任务。它们将更快实施,但如果权衡不符合您的要求,您将不得不选择#1。

答案 1 :(得分:1)

如果你真的想要没有重复,你需要'套'。例如,NHibernate使用Iesi.Collections来提供这样的功能。以Iesi为例,您可以围绕提供的“Set”类(DictionarySet,HashSet,SortedSet)构建自己的功能。资料来源:http://www.codeproject.com/KB/recipes/sets.aspx

答案 2 :(得分:-2)

您可以简单地使用ConcurrentQueue,然后在调用Enqueue之前通过调用ConcurrentQueue.Contains<>方法检查数据是否在队列中。我猜测Contains<>扩展方法已得到很好的优化。

编辑: 正如其他人已经指出的那样,为了实现这一点,你必须在Contains<>方法和Enqueue方法周围使用锁定机制(如互斥锁等),如下所示:

get mutex
if not Contains<>
{
    Enqueue
}
release mutex