Kann ConcurrentDictionary.TryAdd fehlschlagen?

75

Dies ist eher eine akademische Frage ... aber kann ConcurrentDictionary.TryAdd fehlschlagen? Und wenn ja, in welchen Fällen und warum?

Dave Lawrence
quelle
1
Diese Frage ist derzeit ziemlich vage. Die MSDN- Seite dokumentiert einige außergewöhnliche und andere Gründe (wie in den bisherigen Antworten erwähnt).
Christian.K
15
Ja, und die MSDN-Dokumentation ist bekannt für ihre Klarheit und Fehlerfreiheit
Dave Lawrence
4
Nun, es scheint klar und fehlerfrei genug für die anderen Antworten.
Christian.K
13
MSDN ist vielleicht nicht perfekt, aber ich muss noch mit einer Sprache arbeiten, die besser dokumentiert ist als C # /. NET. Bei anderen Sprachen denke ich meistens darüber nach, wie viel besser die Dokumentation wäre, wenn sie eher wie MSDN wäre.
Michael Richardson
2
NET 4.0 Es gibt einen Fall, in dem eine ASP.NET-Web-API-Anwendung gelegentlich alle nachfolgenden TryAdd-Aufrufe mit einer IndexOutOfRangeException fehlschlägt. Dies geschieht auf einem Server in einem Pool, bis der Server gezogen und der App-Pool zurückgesetzt wird. Wir haben noch keinen geeigneten Weg gefunden, um dies anzugehen.
David North

Antworten:

109

Ja kann es, hier sind die Bedingungen ( von msdn ):

  • ArgumentNullException - wenn der Schlüssel eine Nullreferenz ist
  • OverflowException - wenn die maximale Anzahl von Elementen erreicht wurde
  • Es wird false zurückgegeben, wenn bereits ein Element mit demselben Schlüssel vorhanden ist

Nur um es noch einmal zu wiederholen, dies hat nichts mit Parallelität zu tun. Wenn Sie sich Sorgen machen, dass zwei Threads gleichzeitig ein Element einfügen, kann Folgendes passieren:

  • Beide Einsätze funktionieren einwandfrei, wenn die Tasten unterschiedlich sind.
  • Eine Einfügung funktioniert einwandfrei und gibt true zurück, die andere Einfügung schlägt fehl (ohne Ausnahme) und gibt false zurück. Dies geschieht, wenn zwei Threads versuchen, einen Artikel mit demselben Schlüssel einzufügen, und im Grunde nur einer gewinnt und der andere verliert.
oleksii
quelle
4
Ok ... also nichts mit gleichzeitigem Zugriff zu tun ... es führt nur die gleichen Überprüfungen durch, die man mit einem Standardwörterbuch machen müsste.
Dave Lawrence
1
Ja, intern wird CPU-Spinning verwendet, wodurch mehrere gleichzeitige Verbindungen möglich sind.
Oleksii
Danke. Ich akzeptiere Ihre Antwort als die konstruktivste. Wir debuggen hier einen ziemlich schwer fassbaren Fehler und schließen mögliche Quellen Zeile für Zeile aus. Ich kann TryAdd basierend auf dem, was Sie beigetragen haben, ausschließen (obwohl ich immer noch zusätzliche Protokollierung hinzufügen werde, falls das Hinzufügen fehlschlägt)
Dave Lawrence
2
@deveL Es ist normalerweise sehr schwierig, Multithread-Anwendungen zu debuggen. Aber ich würde dem System.Collections.ConcurrentNamespace vertrauen, da er ausgiebig getestet wurde. Schauen Sie sich auch Parallel Nunit an . Ich habe nie damit gearbeitet, aber es scheint das Problem des parallelen Testens von Codeeinheiten zu lösen. Es sollte andere Frameworks dafür geben, wenn Sie NUnit nicht verwenden.
Oleksii
1
Ein erneuter Versuch des Parlaments würde das gleiche Ergebnis liefern und es sinnlos machen. Die Rückgabe von false bedeutet nicht "Ich habe das Einfügen des Elements fehlgeschlagen", sondern "etwas anderes hat das Element bereits eingefügt"
Jim Wolff
8

Sicher kann es. Wenn der Schlüssel bereits vorhanden ist, gibt die Methode false zurück.

Ref: http://msdn.microsoft.com/en-us/library/dd267291.aspx

Rückgabewert Typ: System.Boolean true, wenn das Schlüssel / Wert-Paar erfolgreich zum ConcurrentDictionary hinzugefügt wurde. Wenn der Schlüssel bereits vorhanden ist, gibt diese Methode false zurück.

Chris Gessler
quelle
Nun ... das ist eine Selbstverständlichkeit. Ist das der einzige Fall, in dem es fehlschlagen kann?
Dave Lawrence
@daveL - ja, wenn Ausnahmen auftreten ... siehe Oleksiis Antwort.
Chris Gessler
Vielen Dank für Ihre Hilfe .. Ich + 1ed Sie
Dave Lawrence
1
Angesichts der erklärten Absicht der Funktion, Ihnen mitzuteilen, ob das Element hinzugefügt wurde oder bereits vorhanden war, halte ich die Rückgabe von false nicht für einen Fehler.
Niall Connaughton
2

Es schlägt fehl, wenn der Schlüssel bereits im Wörterbuch vorhanden ist.

Wenn der Wert nicht hinzugefügt werden kann, weil Ihnen der Speicher ausgeht, wird stattdessen eine Ausnahme angezeigt.

Guffa
quelle