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

Cha*_*eld 30 c# concurrent-programming

我只是用这个代码作为例子.假设我有以下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;
    }
}
Run Code Online (Sandbox Code Playgroud)

}

主要计划

static void Main(string[] args)
    {
        ConcurrentDictionary<int, Person> personColl = new ConcurrentDictionary<int,   Person>();

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





    }
Run Code Online (Sandbox Code Playgroud)
  1. 这是迭代并发字典的安全方法吗?如果没有,这样做的安全方法是什么?

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

Jon*_*eet 50

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

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

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

下一个:

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

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

Person ignored;
dictionary.TryRemove(key, out ignored);
Run Code Online (Sandbox Code Playgroud)

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

  • 我看到了这个问题,并立即知道Jon Skeet会得到一个答案.瞧瞧! (4认同)