C# 我可以简化我的ConcurrentDictionary吗;添加或更新";方法?
我有这样的代码:C# 我可以简化我的ConcurrentDictionary吗;添加或更新";方法?,c#,.net,concurrentdictionary,C#,.net,Concurrentdictionary,我有这样的代码: public ConcurrentDictionary<Guid, DeviceItem> deviceStatesCache = new ConcurrentDictionary<Guid, DeviceItem>(); private readonly object deviceStatesCacheLock = new object(); public void StoreDeviceStateInCache(Guid guid, DeviceI
public ConcurrentDictionary<Guid, DeviceItem> deviceStatesCache = new ConcurrentDictionary<Guid, DeviceItem>();
private readonly object deviceStatesCacheLock = new object();
public void StoreDeviceStateInCache(Guid guid, DeviceItem deviceState)
{
bool added, removed, updated = false;
lock (deviceStatesCacheLock)
{
added = deviceStatesCache.TryAdd(guid, deviceState);
if (!added) {
removed = deviceStatesCache.TryRemove(guid, out var _);
if (removed)
{
updated = deviceStatesCache.TryAdd(guid, deviceState);
}
}
}
if (!updated)
throw new Exception("WTF: cannot update deviceStatesCache!");
}
private QueryDevicesResponse CreateQueryDevicesResponse()
{
var deviceItems = new List<DeviceItem>();
lock (deviceStatesCacheLock)
{
foreach (var item in deviceStatesCache)
{
deviceItems.Add(item.Value);
}
}
var response = new QueryDevicesResponse()
{
eventData = new QueryDevicesResponse.EventData()
{
devices = deviceItems
}
};
// response.eventSourceGuid = Guid.Empty.ToString();
return response;
}
公共ConcurrentDictionary设备statesCache=new ConcurrentDictionary();
私有只读对象deviceStatesCacheLock=新对象();
公用void存储设备状态缓存(Guid、DeviceItem设备状态)
{
bool添加、删除、更新=false;
锁(设备状态锁)
{
added=deviceStatesCache.TryAdd(guid,deviceState);
如果(!已添加){
removed=deviceStatesCache.TryRemove(guid,out var);
如果(已删除)
{
updated=deviceStatesCache.TryAdd(guid,deviceState);
}
}
}
如果(!已更新)
抛出新异常(“WTF:无法更新deviceStatesCache!”);
}
专用QueryDeviceResponse CreateQueryDeviceResponse()的
{
var deviceItems=新列表();
锁(设备状态锁)
{
foreach(deviceStatesCache中的var项目)
{
添加设备项(项值);
}
}
var response=newQueryDeviceResponse()
{
eventData=new QueryDeviceResponse.eventData()
{
设备=设备项
}
};
//response.eventSourceGuid=Guid.Empty.ToString();
返回响应;
}
(编辑)
我的锁
应该在以下情况下工作:
StoreDeviceStateInCache
方法中的项介于remove和insert之间时尝试获取值(并且仅此)
createQueryDeviceResponse()方法中的所有项时
StoreDeviceStateInCache()
方法吗?
我知道存在AddOrUpdate方法,但我觉得它没有什么帮助,因为我必须定义其他方法,而这些方法看起来不如我的代码可读
类似于deviceStatesCache[guid]=deviceState代码>应该足够了
我能稍微简化一下createQueryDeviceResponse()
方法并“原子地”阅读完整的词典吗?
(WTF代表“多么可怕的失败”当然是一种例外)如果我正确理解了您的代码,您希望在密钥不存在时添加字典条目,如果密钥存在,则替换字典条目
您可以通过使用ConcurrentDictionary的索引器来实现这一点,而无需任何额外的锁定:
deviceStatesCache[guid] = deviceState;
您还可以使用ConcurrentDictionary类型的AddOrUpdate方法来实现这一点。像下面这样
deviceStatesCache.AddOrUpdate(guid,deviceState,(键,值)=>deviceState) 请准确解释您的操作应该执行什么操作,以及您的目标是什么类型的线程安全。简化代码的一种方法是用普通的字典替换ConcurrentDictionary
。如果您必须锁定任何ConcurrentDictionary
的成员,那么您必须锁定所有成员(否则它将不会是线程安全的)。在这种情况下,ConcurrentDictionary
的所有优点都消失了,剩下的就是它的缺点(不方便的API和同步开销).你能解释一下我应该在你的例子中把什么输入到key
和value
中吗?@Kamil:key
和value
只是lambda参数的任意名称,在本例中其值是未使用的。当ConcurrentDictionary调用lambda时,它将分别传递guid
的值和deviceStatesCache[guid]
的现有值。