ConcurrentDictionary mit mehreren Werten pro Schlüssel, wobei leere Einträge entfernt werdenC#

Ein Treffpunkt für C#-Programmierer
Guest
 ConcurrentDictionary mit mehreren Werten pro Schlüssel, wobei leere Einträge entfernt werden

Post by Guest »

ConcurrentDictionary eignet sich gut für gleichzeitige Situationen, in denen Schlüssel jeweils einem einzelnen Wert zugeordnet werden. Bei der Zuordnung zu mehreren Werten ist es einfach, ein ConcurrentDictionary zu erstellen und dessen Hinzufügungs-/Entfernungsfunktionen zu schützen.

Code: Select all

ConcurrentDictionary  d;

// Add
var list = d.GetOrAdd ("key", x => new List ());
lock (list) {
list.Add ("value to add");
}

// Remove
if (d.TryGetValue ("key", out var list)) {
lock (list) {
list.Remove ("value to remove");
}
}
Allerdings wurde oben davon ausgegangen, dass leere Listen verbleiben dürfen. Das will ich nicht. Aber das Entfernen leerer Paare scheint auf atomare Weise nicht möglich zu sein. Man könnte versuchen:

Code: Select all

if (d.TryGetValue ("key", out var list)) {
lock (list) {
if (list.Remove ("value to remove") && list.Count == 0) {
d.TryRemove ("key", out _);
}
}
}
Aber dies hat eine Race-Bedingung, wenn ein anderer Thread die Liste zuvor erfasst, sie aber ergänzt, nachdem sie geleert und an anderer Stelle entfernt wurde:
  • A: Liste abrufen
  • B: Liste abrufen
  • B: sperren, aus Liste entfernen< /li>
    B: Liste ist leer, Schlüssel löschen, entsperren
  • A: Sperren, zur Liste hinzufügen, entsperren
Das Sperren des Wörterbuchs ist nicht möglich (es ist ein anderer Anwendungsfall).
Soweit ich das beurteilen kann, würde eine Lösung normalerweise mithilfe von Vergleichs- und Austauschoperationen und dem Ersetzen der Liste durch z. B. gefunden werden. ein unveränderliches Array, das dann vollständig ersetzt wird. Da ConcurrentDictionary jedoch kein TryRemove mit einem erwarteten-Wert zum Vergleich anbietet, verstehe ich nicht ganz, wie das geht. Möglicherweise gibt es eine zweistufige Lösung?

Die Verwendung des out-Parameters von TryRemove zum erneuten Hinzufügen von Werten nach dem Entfernen (um Race-Fälle zu beheben) ist nicht möglich - Das Wörterbuch wäre kurzzeitig in einem inkonsistenten Zustand.

Auf dieser Website gibt es viele Fragen zu ähnlichen Szenarien, aber die meisten davon weisen triviale Fehler auf oder werden nicht entfernt leere Einträge. Es gibt diese sehr verwandte Frage, die fragt, ob dies möglich ist. Leider ist es fünf Jahre alt, hat sehr wenig Beachtung gefunden und es gibt keine andere Lösung als den Rückgriff auf Schlösser (was seinen Zweck zunichte macht). Möglicherweise hat sich seitdem ein besserer Weg ergeben.



(Beispiel zur Verdeutlichung bearbeitet)

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post