【发布时间】:2020-03-19 03:01:29
【问题描述】:
有很多关于对 ConcurrentDictionary 进行线程安全更改的帖子,但是,我搜索的所有示例都与更改整个值有关。我认为这是一个稍微不同的问题..
我正在寻求有关更改已在 ConcurrentDictionary 中的对象值的属性的最佳方法的一些指导?
例如,我可以执行以下操作,但不确定它是否是线程安全的
CustomObject obj;
if (customObjectDictionary.TryGetValue(objectKeyToChangeProperty, out obj))
{
obj.Property2 = "NewData";
}
另一种方法是使用 ToArray 复制字典,然后获取所需的对象,修改属性,然后使用线程安全的 AddOrUpdate 方法
obj = customObjectDictionary.ToArray().Select(x => x.Value).FirstOrDefault();
if(obj != null)
{
obj.Property2 = "NewData";
customObjectDictionary.AddOrUpdate(obj.Key, obj, (oldkey, oldvalue) => obj);
}
这样做似乎有点冗长,并且不确定如果多次这样做,调用 ToArray 是否会高效。
示例代码如下:
public partial class Form1 : Form
{
private ConcurrentDictionary<int, CustomObject> customObjectDictionary { get; set; }
public Form1()
{
InitializeComponent();
InitialzeObjects();
Start();
}
private void InitialzeObjects()
{
customObjectDictionary = new ConcurrentDictionary<int, CustomObject>();
var o1 = new CustomObject() { Key = 1, Property1 = 1, Property2 = "Object1" };
customObjectDictionary.AddOrUpdate(o1.Key, o1, (oldkey, oldvalue) => o1);
var o2 = new CustomObject() { Key = 2, Property1 = 2, Property2 = "Object2" };
customObjectDictionary.AddOrUpdate(o2.Key, o2, (oldkey, oldvalue) => o2);
}
private async void Start()
{
bool complete = await Task.Run(() => Test());
}
private async Task<bool> Test()
{
int objectKeyToChangeProperty = 2;
CustomObject obj;
// Method 1 change local variable directly
if (customObjectDictionary.TryGetValue(objectKeyToChangeProperty, out obj))
{
obj.Property2 = "NewData";
}
// Method 2 - make copy first then
obj = customObjectDictionary.ToArray().Select(x => x.Value).FirstOrDefault();
if(obj != null)
{
obj.Property2 = "NewData";
customObjectDictionary.AddOrUpdate(obj.Key, obj, (oldkey, oldvalue) => obj);
}
return true;
}
}
public class CustomObject
{
public int Key { get; set; }
public int Property1 { get; set; }
public string Property2 { get; set; }
}
【问题讨论】:
标签: c#