我有一个ConcurrentDictionaryWrapper
类,它包装了ConcurrentDictionary<K,V>
并实现了IProducerConsumerCollection
接口,这样我就可以将其与BlockingCollection
一起使用。生产者将使用一个键将值添加到BlockingCollection中。思路是,如果键存在,则替换底层字典中的值。我的ConcurrentDictionaryWrapper.TryAdd()
方法如下:
public bool TryAdd(KeyValuePair<TKey, TValue> item)
{
_wrapped[item.Key] = item.Value
return true;
}
我看到的问题是,如果值被替换,BlockingCollection将视其为添加操作。
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
在
TryAdd()
中我无法返回false,因为BlockingCollection会引发InvalidOperationException异常。有没有办法实现我想要的行为呢?我希望这尽可能简单,但似乎没有一种方法可以通过仅实现
IProducerConsumerCollection
来实现具有“添加或更新”行为的BlockingCollection。我想避免在调用BlockingCollection上的TryAdd()
之前进行TryTake()
- 我可能会在Dictionary周围使用标准锁并使用AutoResetEvent
同步生产者/消费者。