ConcurrentDictionary和Clear() - 函数。使值导出线程安全而不会丢失数据

时间:2012-01-24 12:52:40

标签: c# multithreading dictionary thread-safety concurrentdictionary

在将值导出到列表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

2 个答案:

答案 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);
}