Существует довольно много сообщений о поточно-ориентированных изменениях в 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; }
}