【发布时间】:2010-05-25 00:38:16
【问题描述】:
我正在尝试更新 ConcurrentDictionary 中的条目,如下所示:
class Class1
{
public int Counter { get; set; }
}
class Test
{
private ConcurrentDictionary<int, Class1> dict =
new ConcurrentDictionary<int, Class1>();
public void TestIt()
{
foreach (var foo in dict)
{
foo.Value.Counter = foo.Value.Counter + 1; // Simplified example
}
}
}
基本上我需要遍历字典并更新每个值的字段。我从文档中了解到,我需要避免使用 Value 属性。相反,我认为我需要使用 TryUpdate,只是我不想替换整个对象。相反,我想更新对象上的一个字段。
在阅读了 PFX 团队博客上的 this blog entry 之后:也许我需要使用 AddOrUpdate 并且在添加委托中什么都不做。
有没有人知道如何做到这一点?
我的字典中有数以万计的对象,我需要每三十秒左右更新一次。创建新的以更新属性可能是不可行的。我需要克隆现有对象,更新它并替换字典中的那个。我还需要在克隆/添加周期期间锁定它。呸。
我想做的是遍历对象并尽可能直接更新 Counter 属性。
我的最新研究使我找到了 Parallel.ForEach,这听起来不错,但它不应该用于更新状态的操作。
我还看到提到 Interlocked.Increment,这听起来很棒,但我仍然需要弄清楚如何以线程安全的方式在字典中的每个元素上使用它。
【问题讨论】:
-
如果您仅每 30 秒更新一次每个值的字段,实际上是否存在并发?听起来像一个普通的字典和一个 foreach 循环应该是你所需要的。 Parallel.ForEach 也应该可以工作,因为没有共享资源。
-
当更新线程运行时,额外的对象将从其他线程的字典中添加和删除。此外,对象上的其他属性将通过其他线程更新以响应 WCF 消息。所以是的,有很多并发性。感谢您的帮助!
-
好的。然后我的答案仍然存在。使用 AddOrUpdate/GetOrAdd/TryUpdate 等操作字典的内容;迭代时对字典进行快照;更改属性时锁定各个 Class1 实例。
标签: c# concurrency .net-4.0