So fügen Sie ein Element zum Wörterbuch "Parallel loop safe" hinzu

7

Ich habe eine Parallel.ForEach-Schleife, die etwas behandelt. Die erste Operation besteht darin, einen Wert im Wörterbuch hinzuzufügen, wenn der Schlüssel nicht enthalten ist. Ich bekomme einen Fehler beim Hinzufügen, es sagt, dass der Schlüssel bereits im Wörterbuch ist. Ich nehme an, dass der Schlüssel nach dem .Contains-Check dieses Threads, aber vor dem Add durch einen parallelen Prozess hinzugefügt wurde. Gibt es außer der Platzierung dieser Zeile in einem try-catch noch eine andere einfache Lösung, die ich verwenden kann, um diesen Fehler zu vermeiden?

%Vor%     
Amaranth 01.04.2014, 15:37
quelle

3 Antworten

13

Auch außerhalb deiner Race Condition ist Dictionary<,> nicht Thread-sicher. Sie sollten ConcurrentDictionary<,> verwenden und in diesem Fall wahrscheinlich die Methode AddOrUpdate , um die Änderung automatisch durchzuführen. (Ich gehe davon aus, dass Sie auch dem "verschachtelten" Wörterbuch einen Wert hinzufügen möchten. Andernfalls sollten Sie TryAdd .)

    
Jon Skeet 01.04.2014, 15:40
quelle
4

Sie können das ConcurrentDictionary in .NET 4.5 verwenden und die Methodenaufrufe ContainsKey und Add durch TryAdd ersetzen. Siehe Ссылка

    
DoctorMick 01.04.2014 15:41
quelle
2

Dies ist ein Lehrbuchbeispiel für einen Fehler "Zeitpunkt der Überprüfung bis Zeitpunkt der Verwendung": Zwischen der Überprüfung, ob das Wörterbuch den Schlüssel und den Add -Aufruf enthält, hat möglicherweise ein anderer Thread das Element bereits eingefügt und die Vorbedingungen von Add .

Die Lösung besteht darin, ein ConcurrentDictionary<T> zu verwenden oder Threads gleichzeitig auszuschließen, indem Sie das Wörterbuch über eine Sperre oder ein anderes Synchronisationstool aktualisieren.

Vielleicht möchten Sie Ihren Code profilieren, um zu überprüfen, ob sich das Abfeuern von Threads lohnt - der Overhead kann in diesem Fall sehr hoch sein.

    
nimish 01.04.2014 15:44
quelle

Tags und Links