2013-07-21 10 views
22

zu iterieren Ich verwende nur diesen Code für ein Beispiel. Angenommen, ich habe die folgende Personenklasse.Ist dies die richtige Methode, um über Concurrentdictionary in C#

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

}

Hauptprogramm

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. ist dies der sichere Weg über eine gleichzeitige Wörterbuch von Iterieren? Wenn nicht, was ist der sichere Weg dafür?

  2. Sagen wir, dass ich ein Person-Objekt aus dem Wörterbuch entfernen möchte. Ich verwende die tryRemove-Methode, aber was mache ich mit dem outPerson-Objekt? die entfernte Person aus dem Wörterbuch ist darin gespeichert. Was mache ich mit dem outPerson-Objekt, um es vollständig zu löschen?

+1

nicht zu pingelig versucht, aber sie sind nicht die Verwendung von statment fehlt: 'System.Collections.Concurrent verwendet;'? –

+2

Es ist da, nur nicht enthalten. –

Antwort

32

ist dies der sichere Weg über eine gleichzeitige Wörterbuch von Iterieren? Wenn nicht, was ist der sichere Weg dafür?

Ja, es ist sicher, dass es keine Ausnahme auslöst. Wenn Elemente nach dem Iterieren hinzugefügt oder entfernt werden, können sie in die Iteration einbezogen werden oder auch nicht. Von dem GetEnumerator documentation:

Der enumerator aus dem Wörterbuch zurück sicher gleichzeitig verwenden, mit liest und schreibt in das Wörterbuch, aber es nicht einen Moment Zeit-in-Time-Snapshot des Wörterbuchs darstellen. Der Inhalt, der durch den Enumerator verfügbar gemacht wird, kann Änderungen enthalten, die an dem Wörterbuch vorgenommen werden, nachdem GetEnumerator aufgerufen wurde.

Next:

Ich verwende die tryRemove Methode, aber was soll ich tun mit dem outPerson Objekt?

Was auch immer Sie wollen, einschließlich nichts. Sie könnten nur das Wörterbuch IDictionary<TKey, TValue> werfen und Remove nennen, oder einfach nur TryRemove verwenden und die Variable ignorieren danach:

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

Es gibt kein Konzept der „Clearing [das Objekt] vollständig“ - wenn Sie keine Referenzen bekommen haben dazu wird es Müll gesammelt. Aber so oder so, es ist nicht mehr im Wörterbuch (zumindest über diesen Schlüssel). Wenn Sie die Variable (ignored oben) nicht an einer anderen Stelle im Code verwenden, wird das Garbage Collection-Objekt nicht gestoppt.

+1

Danke für Ihre Erklärung! Sehr geschätzt. –

+3

Ich sah diese Frage und wusste sofort, dass es eine Antwort von Jon Skeet geben würde .. siehe da! – davnicwil

+0

@ Jon Skeet - Wäre das der richtige Weg, um es zu werfen? IDictionary removefromColl = (IDictionary ) personColl; –

2

Werfen Sie einen Blick auf this Artikel.

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. 

Seit TryRemove wird das Element aus der Sammlung entfernen, könnten Sie den Wert des Schlüssels müssen.

Es ist sicher, es mit foreach iterieren. Sie erhalten keine Ausnahme.

+0

Das OP * hat * den Schlüssel. Was lässt dich denken, dass sie das nicht tun? Und bedenken Sie, dass "Ich verwende diesen Code nur für ein Beispiel" - es gibt keinen Grund zu der Annahme, dass der echte Code nicht mehrere Threads verwenden wird. –

+0

Ich meinte den Wert dessen, was der Schlüssel war. Es muss ein amerikanisches englisches Ding sein. – DarthVader

+0

Aber der Punkt des OP's ist, dass sie * nicht * den Wert wissen müssen, der dem Schlüssel entspricht ... also waren sie nicht sicher, was mit dem 'out'-Parameter zu tun ist. So habe ich es jedenfalls beantwortet ... –

Verwandte Themen