7

Ich suche nach einem readonly-Wörterbuch, auf das von mehreren Threads zugegriffen werden kann. Während ConcurrentDictionary solche Funktionen verfügbar macht, möchte ich nicht den Overhead und die seltsame API haben.Warum ist ReadOnlyDictionary threadsicher?

.Net 4.5 während der Bereitstellung einer solchen Klasse, besagt die Dokumentation, dass nur statische Anrufe sicher sind.

Ich frage mich warum?

+0

Kopie von Microsoft-Dokument: Threadsicherheit Alle öffentlichen und geschützten Mitglieder ConcurrentDictionary sind Thread-sicher und können gleichzeitig von mehreren Threads verwendet werden. –

+3

@KenCheung: Es ist nicht klar, warum dein Kommentar relevant ist. Die Frage zeigt an, dass das OP "ConcurrentDictionary <,>" bereits kennt, fragt aber nach der Sicherheit von 'ReadOnlyDictionary <,>'. –

Antwort

8

ReadOnlyDictionary ist nur ein Wrapper um jedes andere Wörterbuch. Als solches ist es nur so Thread-sicher wie das zugrunde liegende Wörterbuch.

Insbesondere wenn ein Thread das zugrunde liegende Wörterbuch ändert, während ein anderer Thread aus dem Wrapper liest, gibt es keine Garantie für die Sicherheit.

Wenn Sie eine ReadOnlyDictionary wollen, die von alle Winkel effektiv unveränderlich ist, können Sie einen Klon des ursprünglichen Wörterbuch erstellen, eine ReadOnlyDictionary Wrapper um das erstellen und dann einen Verweis auf den Klon überall halten. Mit nur lesen Operationen laufen, sollte es dann Thread-sicher sein. Wenn die Schlüssel- oder Werttypen veränderbar sind, eröffnet das natürlich einen zweiten Grad an "Thread-Unsicherheit", um den man sich kümmern muss.

+0

Ich dachte es auch. Vielen Dank. – Mouk

+3

Nur eine Klarstellung. Schreibgeschützt bedeutet nicht Thread-sicher. Was passiert, wenn das Wörterbuch die Elemente basierend auf der Leseverwendung neu anordnet? Die BCL-Wörterbücher machen das nicht (AFAIK), aber ich habe irgendwo gelesen, dass Scripting.Dictionary das letzte gelesene Element an die erste Stelle im Bucket verschiebt. – adrianm

+1

@adrianm: Ja, das stimmt. Aber Sie könnten ein 'System.Collections.Generic.Dictionary' einbinden, das nie modifiziert wurde, und * das * wäre in Ordnung. –