我可以简化ConcurrentDictionary的“添加或更新”方法吗?

问题描述

我有这样的代码

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

(编辑)

我的lock应该可以在以下情况下工作:

  1. 当另一个线程试图在StoreDeviceStateInCache方法(仅此)之间的删除和插入之间获取值时。

  2. 当另一个线程开始以createqueryDevicesResponse()方法读取所有项目时。

我可以简化一下StoreDeviceStateInCache()方法吗?

我知道AddOrUpdate方法存在,但是由于必须定义其他方法,而且看起来比我的代码可读性差,因此我找不到它。

看起来Michael Liu suggestiondeviceStatesCache[guid] = deviceState;就足够了

我可以稍微简化createqueryDevicesResponse()方法并“原子地”阅读完整的词典吗?

(WTF当然代表“多么严重的失败”)

解决方法

如果我正确地理解了您的代码,那么如果键不存在,则要添加一个字典条目,如果键不存在,则要替换字典条目。

您可以使用ConcurrentDictionary的索引器来完成此操作,而无需任何其他锁定:

deviceStatesCache[guid] = deviceState;
,

您也可以使用ConcurrentDictionary类型的AddOrUpdate方法来实现此目的。像下面这样

deviceStatesCache.AddOrUpdate(guid,deviceState,(key,value)=> deviceState);

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...