我需要以线程安全的方式获取ConcurrentDictionary的每个项目(string,List)
使用以下结构是否安全?
foreach (var item in concurrentDict)
{
var readonlyCollection = item.Value.AsReadOnly();
//use readonly collection, (I need only Values of the concurrent dictionary)
}
我想使用字典安全的值。
答案 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");
}
}