更新的ConcurrentDictionary值的字段 [英] Updating fields of values in a ConcurrentDictionary
问题描述
我想以更新ConcurrentDictionary像这样的条目:
I am trying to update entries in a ConcurrentDictionary something like this:
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只是我不想取代我的整个对象。相反,我要在对象上更新的字段。
Essentially I need to iterate over the dictionary and update a field on each Value. I understand from the documentation that I need to avoid using the Value property. Instead I think I need to use TryUpdate except that I don’t want to replace my whole object. Instead, I want to update a field on the object.
在阅读在PFX团队博客这个博客条目:也许我需要使用AddOrUpdate和干脆什么也不做,在附加委托。
After reading this blog entry on the PFX team blog: Perhaps I need to use AddOrUpdate and simply do nothing in the add delegate.
没有任何人有任何见解,如何做到这一点?
Does anyone have any insight as to how to do this?
我在字典对象,我需要每三十秒左右更新数万。为了更新属性创建新的可能是不可行的。我需要克隆现有对象,对其进行更新和替换一个在字典中。我也很需要,将其锁定为克隆的持续时间/加周期。呸。
I have tens of thousands of objects in the dictionary which I need to update every thirty seconds or so. Creating new ones in order to update the property is probably not feasible. I would need to clone the existing object, update it and replace the one in the dictionary. I’d also need to lock it for the duration of the clone/add cycle. Yuck.
我想直接如果可能的话做的是迭代的对象和更新计数属性。
What I’d like to do is iterate over the objects and update the Counter property directly if possible.
我最近的研究已经使我以Parallel.ForEach这听起来不错,但它不应该被用于该更新状态的行动。
My latest research has led me to to Parallel.ForEach which sounds great but it is not supposed to be used for actions that update state.
我也看了一提Interlocked.Increment的这听起来不错,但我仍然需要弄清楚如何使用它的每个元素在我的字典里一个线程安全的方式。
I also saw mention of Interlocked.Increment which sounds great but I still need to figure out how to use it on each element in my dictionary in a thread safe way.
推荐答案
首先,解决你的问题锁定:
First, to solve your locking problem:
class Class1
{
// this must be a variable so that we can pass it by ref into Interlocked.Increment.
private int counter;
public int Counter
{
get{return counter; }
}
public void Increment()
{
// this is about as thread safe as you can get.
// From MSDN: Increments a specified variable and stores the result, as an atomic operation.
Interlocked.Increment(ref counter);
// you can return the result of Increment if you want the new value,
//but DO NOT set the counter to the result :[i.e. counter = Interlocked.Increment(ref counter);] This will break the atomicity.
}
}
迭代刚刚值应该比迭代的键值对速度更快。 [虽然我觉得遍历键列表,做一下起坐会更快还在ConcurrentDictionary在大多数情况下。]
Iterating the just values should be faster than iterating the key value pair. [Though I think iterating a list of keys and doing the look-ups will be faster still on the ConcurrentDictionary in most situations.]
class Test
{
private ConcurrentDictionary<int, Class1> dictionary = new ConcurrentDictionary<int, Class1>();
public void TestIt()
{
foreach (var foo in dictionary.Values)
{
foo.Increment();
}
}
public void TestItParallel()
{
Parallel.ForEach(dictionary.Values,x=>x.Increment() );
}
}
这篇关于更新的ConcurrentDictionary值的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!