在将值导出到列表ex并清除该字典之后的条件下,使ConcurrentDictionary线程安全的任何想法。这样任何其他线程都无法在导出和清除之间添加数据。
像这样: “
List<data> list;
list = (List<data>)_changedItems.Values; //get values before clearing
_changedItems.Clear();
” 并且使用函数_changedItems.AddOrUpdate
通过其他线程完成添加现在,如果某个线程在清算行之前将数据对象添加到集合中,则有可能在从字典中删除数据和清除内容之间丢失新数据。
或者是添加和清除内部锁定的唯一方法。
lock(object)
{
List<data> list;
list = (List<data>)_changedItems.Values;
_changedItems.Clear();
}
并且
lock(object)
_changedItems.AddOrUpdate
需要一个Clear-function,可以安全地从词典中返回所有已清除的项目。
-Larry
答案 0 :(得分:2)
实际上,在序列中调用两个线程安全的方法并不能保证序列本身的原子性。你是对的,需要lock
两次调用才能获得值和清除。
答案 1 :(得分:0)
您可以使用TryRemove(key, out value)
方法。它返回已删除的元素。这样您就不必锁定字典来移动缓冲数据。
List<data> list;
var keys = dict.Keys;
foreach(var key in keys)
{
data value;
dict.TryRemove(key, out value);
list.Add(value);
}
更新:实际上,即使在更改时,您也可以直接在 ConcurrentDictionary 上进行迭代。这样您就不必从属性.Keys
构建密钥集合,这可能是(?)慢,具体取决于实现。
List<data> list;
foreach(var kvp in dict)
{
data value;
dict.TryRemove(kvp.Key, out value);
list.Add(value);
}