Frage

Ich habe bemerkt, dass Sie Queue.Synchronize nennen kann eine Thread-sichere Warteschlange-Objekt zu erhalten, aber die gleiche Methode ist auf Queue nicht verfügbar . Weiß jemand, warum? Scheint irgendwie komisch.

War es hilfreich?

Lösung

Aktualisieren - in .NET 4, gibt es jetzt ConcurrentQueue<T> in System.Collections.Concurrent, wie hier dokumentiert http://msdn.microsoft.com/en-us/library/dd267265.aspx . Es ist interessant festzustellen, dass seine IsSynchronized Methode (zu Recht) den Wert false zurück.

ConcurrentQueue<T> ist ein kompletter Grund auf Rewrite, Erstellen von Kopien der Warteschlange aufzuzuzählen, und keine Blockiertechniken wie Interlocked.CompareExchange() und Thread.SpinWait() Advanced.

Der Rest dieser Antwort noch relevant ist, soweit sie auf das Ende des alten synchronisieren () und SyncRoot Mitglieder bezieht, und warum sie funktionierten nicht sehr gut aus einer API-Perspektive.


Wie pro Zooba Kommentar entschied das BCL-Team, dass zu viele Entwickler dazu, synchronisieren Missverständnisse wurden (und in geringerem Maße, SyncRoot)

Brian Grunkemeyer beschrieb dies am BCL Team Blog ein paar Jahre zurück: http://blogs.msdn.com/bclteam/archive/ 2005/03/15 / 396399.aspx

Die zentrale Frage ist immer die richtige Granularität um Schlösser, wo einige Entwickler naiverweise mehrere Eigenschaften oder Methoden verwenden würden auf einer „synchronisiert“ Sammlung und glauben, dass ihr Code Thread sicher zu sein. Brian verwendet Queue als sein Beispiel:

if (queue.Count > 0) {
    object obj = null;
    try {
        obj = queue.Dequeue();

Entwickler würde nicht, dass Graf erkennen konnten von einem anderen Thread geändert werden, bevor Dequeue aufgerufen wurde.

Entwickler Erzwingen eine explizite Sperre Anweisung um den gesamten Betrieb zu verwenden, bedeutet dies, falsches Gefühl der Sicherheit zu verhindern.

Wie Brian erwähnt, war die Entfernung von SyncRoot zum Teil, weil es in erster Linie eingeführt worden war Synchronized zu unterstützen, sondern auch, weil in vielen Fällen gibt es eine bessere Wahl des Sperrobjekts - die meiste Zeit entweder die Queue-Instanz selbst oder a

private static object lockObjForQueueOperations = new object();

auf die Klasse der Instanz der Queue zu besitzen ...

Dieser letztere Ansatz ist in der Regel am sichersten, da es einige andere gemeinsame Fallen vermeidet:

Wie sie sagen, Threading hart ist, und macht es einfach scheinen kann gefährlich sein.

Andere Tipps

Sie können die Parallel CTP lohnt sich finden; hier ist ein Blog-Eintrag von den Jungs, die es zusammen, das ist ziemlich aktuell setzen:

Aufzählen Concurrent Collections

Es ist nicht ganz die gleiche Sache, aber es könnte Ihr größeres Problem lösen. (Sie haben sogar Queue<T> gegen ConcurrentQueue<T> als Beispiel.)

Es gibt eine jetzt in .Net 4.0:

ConcurrentQueue<T> 

in System.Collections.Concurrent

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

(ich nehme an du meinst Queue für die zweite.)

Ich kann nicht speziell die Frage beantworten, mit der Ausnahme, dass die IsSynchronized und SyncRoot Eigenschaften (aber nicht synchronisieren () explizit) von der Schnittstelle ICollection geerbt. Keiner der generischen Sammlungen verwenden, um dies und die ICollection Schnittstelle nicht SyncRoot enthalten.

Wie, warum es nicht enthalten ist, kann ich nur spekulieren, dass sie entweder in der Art und Weise durch die Bibliothek Designer oder sie einfach nicht genug, um sie in den neueren Sammlungen zu rechtfertigen genutzt wurde bestimmt nicht verwendet werden beibehalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top