首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#如何在BlockingCollection<T>中更新元素?

C#如何在BlockingCollection<T>中更新元素?
EN

Stack Overflow用户
提问于 2013-12-18 12:30:13
回答 2查看 1.7K关注 0票数 3

我有一个ConcurrentDictionaryWrapper类,它封装了ConcurrentDictionary<K,V>并实现了IProducerConsumerCollection接口,所以我可以将它与BlockingCollection一起使用。生产者将用一个键向BlockingCollection添加值。其思想是,如果键存在,我们将替换底层字典中的值。我的ConcurrentDictionaryWrapper.TryAdd()方法如下:

代码语言:javascript
运行
复制
public bool TryAdd(KeyValuePair<TKey, TValue> item)
{
    _wrapped[item.Key] = item.Value
    return true;
}

我看到的问题是,如果该值被替换,BlockingCollection将把它看作是一个附加值。

代码语言:javascript
运行
复制
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。

有什么方法可以达到我想要的行为吗?我希望这尽可能简单,但似乎没有办法通过实现AddOrUpdate来实现BlockingCollection中的“IProducerConsumerCollection”行为。在调用TryTake()之前,我希望避免在BlockingCollection上调用TryAdd() --我可能只是在字典周围使用一个标准锁,并将生产者/消费者与AutoResetEvent同步。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-18 14:00:16

这里存在相当大的摩擦,BlockingCollection<>维护自己的计数,并且不使用IProducerConsumerCollection.Count实现。因此,由于您没有失败TryAdd(),所以BlockingCollection现在确信集合中有两个项。即使你只能找回其中的一个。因此,您当然不能保持原样,您的代码将始终处于死锁状态。

您需要的是一个BlockingCollection方法,如果项已经存在,则返回false或静默失败。但它没有一个,InvalidOperationException是不可避免的。你可以抓住它,但那太丑了。

另一种方法是would ()方法,如果返回true,可以使用该方法来避免调用TryAdd()。但是现在这个收藏不再是线程安全了。这就是为什么BlockingCollection没有这种方法的原因。

这是一个岩石和困难的地方,你不能让它按照设想的工作。你得自己转。最好偷取线程母版的代码,这篇杂志文章中的有界缓冲区应该是正确锁设计的良好开端。

票数 1
EN

Stack Overflow用户

发布于 2013-12-18 13:27:40

也许,将以前的项目标记为无效,而不是替换,可能更适合。保留一个包含每个值的布尔标志。添加带有现有键的项时,查找前一项,将其标志设置为false,并将标志设置为true的新项添加到true。

然后,当使用者获得该项目时,它将检查它是否有效。如果没有,它会扔掉它,并要求新的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20658271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档