Thread-Sicherheit von Dispose-Methoden?

8

MSDN dokumentiert die Thread-Sicherheit von Instanz-Mitgliedern von BCL-Typen ziemlich gut, aber ich habe nie wirklich Informationen gesehen, die angeben, wie die Dispose -Methode von IDisposable -Typen aufgerufen werden kann.

Ist die Methode Dispose a) garantiert Thread-sicher für alle Klassen, b) niemals garantiert thread-safe, c) garantiert Thread-sicher für einige Klassen (wenn ja, wo ist das speziell dokumentiert)?

Wenn schließlich die Dispose -Methode garantiert Thread-sicher ist, bedeutet das, dass ich eine Sperre um jede Instanzmethode in der Klasse setzen muss, die verfügbare Ressourcen verwendet?

Nebenaspekt: ​​Ich bin mir bewusst, dass Finalizer für Typen aufgrund der Art und Weise, in der Garbage Collection in .NET arbeitet (ziemlich aggressiv), threadsicher sein und möglicherweise die Dispose -Methode aufrufen können. Lassen Sie uns dieses Thema für den Punkt hier jedoch beiseite lassen.

    
Noldorin 17.02.2011, 03:52
quelle

3 Antworten

6

Das Thema Thread-Sicherheit und Dispose ist etwas schwierig. Da in vielen Fällen das einzige Ding, das irgendein Thread legitim mit einem Objekt tun kann, sobald ein anderer Thread damit begonnen hat, es zu verwerfen, versuchen würde, es selbst zu beseitigen, würde es auf den ersten Blick als das einzige Ding erscheinen, das notwendig ist, um Thread-Sicherheit zu gewährleisten Verwenden Sie Interlocked.Exchange für eine "Disposed" -Flagge, um sicherzustellen, dass der Dispose-Versuch eines Threads stattfindet und der andere ignoriert wird. In der Tat, das ist ein guter Ausgangspunkt, und ich denke, es sollte Teil des Standard-Dispose-Musters sein (das CompareExchange sollte in der versiegelten Basisklassen-Wrapper-Methode durchgeführt worden sein, um zu vermeiden, dass jede abgeleitete Klasse ihre eigene private verwendet verteilte Flagge). Leider, wenn man bedenkt, was Dispose tatsächlich tut, sind die Dinge viel komplizierter.

Der eigentliche Zweck von Dispose besteht nicht darin, etwas mit dem Objekt zu tun, das entsorgt wird, sondern vielmehr darin, andere Objekte zu bereinigen, auf denen dieses Objekt Referenzen hält. Diese Entitäten können verwaltete Objekte, Systemobjekte oder etwas ganz anderes sein; Sie befinden sich möglicherweise nicht einmal auf demselben Computer wie das zu entsorgende Objekt. Damit Dispose Thread-sicher ist, würden diese anderen Entitäten zulassen, dass Dispose sie zur gleichen Zeit bereinigt, wie andere Threads andere Dinge mit ihnen tun. Einige Objekte können eine solche Verwendung bewältigen; andere können nicht.

Ein besonders ärgerliches Beispiel: Objekte dürfen Ereignisse mit RemoveHandler-Methoden enthalten, die nicht threadsicher sind. Daher sollte jede Dispose-Methode, die Event-Handler bereinigt, nur aus demselben Thread aufgerufen werden, in dem die Subskriptionen erstellt wurden.

    
supercat 17.02.2011, 18:07
quelle
2

Die Seite auf MSDN hier gibt niemals explizit an, dass Dispose-Methoden nicht threadsafe sind , aber zu meinem Lesen, ihr Code impliziert, dass nein, sie sind nicht threadsicher und Sie müssen dies bei Bedarf berücksichtigen.

Insbesondere die Kommentare im Beispielcode:

%Vor%     
David Hall 17.02.2011 04:11
quelle
2

Ich bin mir ziemlich sicher, dass, wenn nicht anders angegeben, die Dispose() -Methode einer Klasse als Instanzelement für die Dokumentation der Thread-Sicherheit zählt oder nicht.

Wenn also in der Dokumentation angegeben wird, dass Instanzenmitglieder nicht threadsicher sind, dann ist auch Dispose() nicht erforderlich, es sei denn, es wird ausdrücklich darauf hingewiesen, dass sie anders als der Rest sind.

    
Andrew Barber 17.02.2011 04:11
quelle