I have a ConcurrentDictionaryWrapper
class that wraps ConcurrentDictionary<K,V>
and implements the IProducerConsumerCollection
interface so I can use it with a BlockingCollection
. Producers will add values to the BlockingCollection with a key. The idea is that if the key exists, we replace the value in the underlying dictionary. My ConcurrentDictionaryWrapper.TryAdd()
method is as follows:
public bool TryAdd(KeyValuePair<TKey, TValue> item)
{
_wrapped[item.Key] = item.Value
return true;
}
The problem I'm seeing is that if the value is replaced, the BlockingCollection will see this as an addition.
var wrapper = new ConcurrentDictionaryWrapper<string, object>();
var bc = new BlockingCollection<KeyValuePair<string, object>>(wrapper);
bc.TryAdd(new KeyValuePair<string, object>("key", new object()));
bc.TryAdd(new KeyValuePair<string, object>("key", new object()));
wrapper.Count; # returns 1
bc.Count; # returns 2
I cannot return false in TryAdd()
above because the BlockingCollection will raise an InvalidOperationException.
Is there a way to achieve the behaviour I want? I want this to be as simple as possible but there doesn't seem to be a way to have this "AddOrUpdate" behaviour with a BlockingCollection by just implementing IProducerConsumerCollection
. I want to avoid having to TryTake()
before calling TryAdd()
on the BlockingCollection — I would probably just use a standard lock around a Dictionary and synchronise the producers/consumers with AutoResetEvent
.