gpt4 book ai didi

c# - 更新 ConcurrentDictionary 中的值字段

转载 作者:可可西里 更新时间:2023-11-01 08:22:15 25 4
gpt4 key购买 nike

我正在尝试像这样更新 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,除非我不想替换整个对象。相反,我想更新对象上的一个字段。

看完this blog entry在 PFX 团队博客上:也许我需要使用 AddOrUpdate 并且在添加委托(delegate)中什么都不做。

有没有人知道如何做到这一点?


我的字典中有数以万计的对象,我需要每三十秒左右更新一次。创建新的以更新属性可能是不可行的。我需要克隆现有对象,更新它并替换字典中的对象。我还需要在克隆/添加周期期间锁定它。呸。

我想做的是迭代对象并在可能的情况下直接更新 Counter 属性。

我的最新研究让我想到了 Parallel.ForEach,这听起来不错,但它不应该用于更新状态的操作。

我还看到提到了 Interlocked.Increment,这听起来不错,但我仍然需要弄清楚如何以线程安全的方式在我的字典中的每个元素上使用它。

最佳答案

首先,解决你的锁定问题:

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 上迭代键列表并进行查找仍然会更快。]

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() );
}

}

关于c# - 更新 ConcurrentDictionary 中的值字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2901289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com