开发者

How to create no-duplicates ConcurrentQueue?

开发者 https://www.devze.com 2023-03-01 15:20 出处:网络
I need a concurrent collection that doesn\'t allow duplicates (to use in BlockingCollection as Producer/Consumer).

I need a concurrent collection that doesn't allow duplicates (to use in BlockingCollection as Producer/Consumer). I don't need strict order of elements. From another hand i want to minimize the maximum time of element "live" in collection. I.e. collection mustn't be LIFO, ideally it should be FIFO.

Well I would say that I need ConcurrentQueue with no duplicates allowed, but ConcurrentBag with no duplicates also might work.开发者_如何学JAVA

Why C# doesn't contain anything like that and probably someone already created it?

This question is result of my previous question What type of IProducerConsumerCollection<T> to use for my task?


There are no built-in .Net libraries that combine this set of rules for a collection. You have three options:

  1. Write your own collection class
  2. Use two collections: Write a custom class that uses one ConcurrentQueue and any Set-based collection that auto-checks for duplicates; have add to Set run and if successful, add to ConcurrentQueue; each add/remove would add to both collections when successful
  3. Use ConcurrentQueue but iterate through the entire list checking for a duplicate

The last two aren't very efficient (one with memory, the other with CPU, I/O, locking) and are messier because of the need for explicit locking, but would accomplish the task. They will be quicker to implement, but if the trade-offs don't meet your requirements you'll have to go with option #1.


Well if you strictly want to have no duplicates, you need 'Sets'. For instance NHibernate uses Iesi.Collections to provide such functionality. Taking Iesi, you can build your own functionality around the provided 'Set' classes (DictionarySet, HashSet, SortedSet). Source: http://www.codeproject.com/KB/recipes/sets.aspx


You could simply use a ConcurrentQueue and before calling Enqueue check if the data is in the queue by calling the ConcurrentQueue.Contains<> method. I'm guessing the Contains<> extension method is fairly well optimized.

EDIT: As others have noted, for this to work it would you'd have to use a locking mechanism such as a mutex etc around the Contains<> method and the Enqueue method like this:

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

精彩评论

暂无评论...
验证码 换一张
取 消