并发字典安全用法

时间:2017-12-19 20:57:57

标签: c# concurrentdictionary

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

使用以下结构是否安全?

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

我想使用字典安全的值。

1 个答案:

答案 0 :(得分:0)

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

但是,您需要注意item.Value类型List,因为列表不是线程安全的。如果另一个线程在你在循环中读取它时修改了一个列表,你可能会遇到异常。

在列表中调用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");
    }
}