这是在C#中迭代Concurrentdictionary的正确方法吗?

我只是用这个代码作为例子。 假设我有以下Person类。

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace dictionaryDisplay { class Person { public string FirstName { get; private set;} public string LastName { get; private set; } public Person(string firstName, string lastName) { this.FirstName = firstName; this.LastName = lastName; } public override string ToString() { return this.FirstName + " " + this.LastName; } } 

}

主体计划

 static void Main(string[] args) { ConcurrentDictionary personColl = new ConcurrentDictionary(); personColl.TryAdd(0, new Person("Dave","Howells")); personColl.TryAdd(1, new Person("Jastinder","Toor")); Person outPerson = null; personColl.TryRemove(0, out outPerson); //Is this safe to do? foreach (var display in personColl) { Console.WriteLine(display.Value); } } 
  1. 这是迭代并发字典的安全方式吗? 如果没有,这样做的安全方法是什么?

  2. 让我们说我想从字典中删除一个Person对象。 我使用tryRemove方法,但是如何处理outPerson对象呢? 从字典中删除的Person存储在其中。 如何使用outPerson对象完全清除它?

这是迭代并发字典的安全方式吗? 如果没有,这样做的安全方法是什么?

是的,它是安全的,因为它不会抛出exception。 如果在开始迭代后添加或删除元素,则它们可能包含也可能不包含在迭代中。 从GetEnumerator文档:

从字典返回的枚举器可以安全地与字典的读写一起使用,但它不代表字典的即时快照。 通过枚举器公开的内容可能包含在调用GetEnumerator后对字典所做的修改。

下一个:

我使用tryRemove方法,但是如何处理outPerson对象呢?

无论你想要什么,包括什么都没有。 您可以将字典转换为IDictionary并调用Remove ,或者只是使用TryRemove并在之后忽略该变量:

 Person ignored; dictionary.TryRemove(key, out ignored); 

没有“完全清除[对象]”的概念 – 如果你没有任何引用它,它将被垃圾收集。 但无论如何,它不再在字典中(至少通过那个键)。 如果您不在代码中的任何其他位置使用变量(上面ignored ),则不会阻止对象被垃圾回收。

看看这篇文章。

 TryRemove() was added to attempt atomic, safe removes. To safely attempt to remove a value we need to see if the key exists first, this checks for existence and removes under an atomic lock. 

由于TryRemove将从集合中删除该项,因此您可能需要该键的值。

使用foreach迭代它是安全的。 你不会得到例外。