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:
- Write your own collection class
- 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
- 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
精彩评论