并发字典安全使用

Concurrent Dictionary safety usage

我需要线程安全的方式来获取 ConcurrentDictionary(string, List) 的每个项目

使用以下结构安全吗?

foreach (var item in concurrentDict)
{
     var readonlyCollection = item.Value.AsReadOnly();
     //use readonly collection, (I need only Values of the concurrent dictionary)
}

我想使用字典安全值。

foreach 部分很好,但需要注意的是,同时添加的项目可能会或可能不会包含在迭代中。不过你不会得到例外。

但是,您需要小心使用类型为 Listitem.Value,因为列表不是线程安全的。如果在循环中读取列表时另一个线程修改了列表,则可能会出现异常。

在您的列表上调用 AsReadOnly() 没有帮助,因为您得到的是原始列表的包装器。如果从包装器内的原始列表中读取会抛出异常,那么从包装器中读取也会抛出异常。此外,您不能简单地通过对嵌套列表进行浅表复制来解决此问题,因为在复制时可能会执行并发修改。

一种方法是在读写列表时lock列表:

foreach (var item in concurrentDict) {
    List<string> listCopy;
    lock (item.Value) {
        listCopy = item.Value.ToList();
    }
     //use collection copy
}

当一个写线程改变字典里面的列表时,它需要执行相同的锁定:

if (concurrentDict.TryGetValue("mykey", var out list)) {
    lock (list) {
        list.Add("newValue");
    }
}