web-dev-qa-db-fra.com

Est-ce la bonne façon d'itérer sur Concurrentdictionary en C #

J'utilise uniquement ce code pour un exemple. Supposons que j'ai la classe Person suivante.

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

}

Programme principal

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





    }
  1. est-ce le moyen sûr d'itérer sur un dictionnaire simultané? Sinon, quel est le moyen sûr de le faire?

  2. Disons que je veux supprimer un objet Person du dictionnaire. J'utilise la méthode tryRemove, mais que dois-je faire avec l'objet outPerson? la personne supprimée du dictionnaire y est stockée. Que dois-je faire avec l'objet outPerson pour l'effacer complètement?

32
Charles Whitfield

est-ce le moyen sûr d'itérer sur un dictionnaire simultané? Sinon, quel est le moyen sûr de le faire?

Oui, c'est sûr car il ne lèvera pas d'exception. Si des éléments sont ajoutés ou supprimés après avoir commencé l'itération, ils peuvent ou non être inclus dans l'itération. Depuis la documentation GetEnumerator:

L'énumérateur renvoyé par le dictionnaire est sûr à utiliser simultanément avec les lectures et les écritures dans le dictionnaire, mais il ne représente pas un instantané instantané du dictionnaire. Le contenu exposé via l'énumérateur peut contenir des modifications apportées au dictionnaire après l'appel de GetEnumerator.

Prochain:

J'utilise la méthode tryRemove, mais que dois-je faire avec l'objet outPerson?

Tout ce que vous voulez, y compris rien. Vous pouvez simplement convertir le dictionnaire en IDictionary<TKey, TValue> et appelez Remove, ou utilisez simplement TryRemove et ignorez la variable par la suite:

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

Il n'y a pas de concept de "vider [l'objet] complètement" - si vous n'avez pas de références, il sera récupéré. Mais de toute façon, ce n'est plus dans le dictionnaire (au moins via cette clé). Si vous n'utilisez la variable (ignored ci-dessus) nulle part ailleurs dans le code, cela n'empêchera pas l'objet d'être récupéré.

46
Jon Skeet

Jetez un œil à l'article this .

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.

Étant donné que TryRemove supprimera l'élément de la collection, vous devrez peut-être la valeur de la clé.

Il est sûr de l'itérer avec foreach. Vous n'aurez pas d'exception.

2
DarthVader