Frage

Wann würde ich IDispose auf eine Klasse implementieren, wie zu einem destructor Gegensatz? Ich las diesem Artikel , aber ich bin noch vermisst den Punkt .

Meine Vermutung ist, dass, wenn ich IDispose auf einem Objekt implementieren, kann ich explizit ‚zerstört‘ es im Gegensatz zu dem Garbage Collector zu warten, es zu tun. Ist das richtig?

Heißt das, ich sollte immer explizit Dispose für ein Objekt aufrufen? Was sind einige Beispiele dafür?

War es hilfreich?

Lösung

Ein Finalizerthread (aka destructor) ist Teil der Garbage Collection (GC) - es unbestimmt ist, wenn (oder auch wenn) dies geschieht, wie GC in erster Linie als Folge des Speicherdruckes geschieht (das heißt mehr Platz benötigen). Finalizers sind nur in der Regel verwendet zur Reinigung nicht verwalteten Ressourcen, da verwalteten Ressourcen werden ihre eigene Sammlung / Entsorgung haben.

Daher IDisposable auf deterministisch verwendet aufzuräumen Objekte, das heißt jetzt. Es ist nicht das Gedächtnis des Objekts sammeln (die GC gehört noch.) - aber zum Beispiel verwendet wird, Dateien, Datenbankverbindungen zu schließen, usw.

Es gibt viele vorherigen Themen dazu:

Schließlich ist zu beachten, dass es nicht ungewöhnlich, dass ein IDisposable Objekt ist auch eine Finalizerthread hat; in diesem Fall ruft Dispose() in der Regel GC.SuppressFinalize(this), was bedeutet, dass GC nicht die Finalizerthread läuft - es wirft einfach den Speicher entfernt (viel billiger). Der Finalizer läuft immer noch, wenn Sie vergessen, das Objekt Dispose().

Andere Tipps

Die Rolle der Finalize() Methode, um sicherzustellen, dass ein .NET-Objekt nicht verwalteten Ressourcen aufzuzuräumen , wenn Müll gesammelt . Allerdings Objekte wie Datenbankverbindungen oder Datei-Handler sollte so schnell wie möglich gelöst werden, anstatt sich auf auf die Garbage Collection zu verlassen. Dafür sollten Sie IDisposable Schnittstelle und lassen Sie Ihre Ressourcen im Dispose() Methode implementieren.

Es gibt eine sehr gute Beschreibung auf MSDN :

  

Die primäre Verwendung dieser Schnittstelle ist    Freigabe von nicht verwalteten Ressourcen .   Der Garbage Collector automatisch   die Speichermitteilungen , um eine zugewiesene   Objekt verwaltet werden, wenn das Objekt nicht ist   mehr verwendet. Allerdings ist es nicht   möglich, wenn Müll vorherzusagen   Sammlung auftreten . Außerdem,   der Garbage Collector hat keine   Kenntnisse von nicht verwalteten Ressourcen   wie Fenstergriffe oder offen   Dateien und Bäche.

     

Verwenden Sie die Methode Dispose dieser   Schnittstelle zu explizit freigeben   nicht verwalteten Ressourcen in Verbindung   mit dem Garbage-Collector. Das    Verbraucher eines Objekts kann diese Methode aufrufen, wenn das Objekt nicht   mehr benötigt wird.

Das einzige, was in einer C # destructor sein soll, ist diese Zeile:

Dispose(False);

Das ist es. Nichts anderes jemals in diesem Verfahren sein sollte.

Ihre Frage, ob und warum Sie immer Dispose sollten nennen, ist in der Regel eine hitzige Debatte. Siehe dieses Blog eine interessante Perspektive von angesehenen Persönlichkeiten in der .NET-Community.

Ich persönlich denke, Jeffrey Richter die Position, dass Dispose Aufruf nicht zwingend ist unglaublich schwach. Er gibt zwei Beispiele, um seine Meinung zu rechtfertigen.

Im ersten Beispiel sagt er Dispose auf Windows Forms-Steuerelemente Aufruf ist umständlich und unnötig in Mainstream-Szenarien. Allerdings scheitert er, dass Dispose zu erwähnen tatsächlich automatisch durch die Steuer Container in den Mainstream-Szenarien genannt wird.

Im zweiten Beispiel stellt er fest, dass ein Entwickler anzunehmen, dass die Instanz von IAsyncResult.WaitHandle aggressiv angeordnet sein sollte, ohne zu bemerken, dass die Eigenschaft lazily den Griff Warte initialisiert zu einer unnötigen Leistungseinbuße zur Folge hat. Aber das Problem mit diesem Beispiel, dass die IAsyncResult sich nicht auf Microsofts eigene veröffentlichten Richtlinien haftet für mit IDisposable Objekten zu tun. Das heißt, wenn eine Klasse eine Referenz auf einen IDisposable Typen hält dann die Klasse selbst IDisposable implementieren sollte. Wenn IAsyncResult diese Regel befolgt, dann könnte seine eigene Dispose Methode, um die Entscheidung treffen in Bezug auf welche seine Bestandteile braucht entsorgen.

Also, wenn jemand hat ein attraktiveres Argument, das ich in dem „immer anrufen Entsorgen“ bleiben werde Lager mit dem Verständnis, dass es geht einige Ränder Fälle sein, die meist aus armen Design-Entscheidungen entstehen.

Es ist ziemlich wirklich einfach. Ich weiß, es beantwortet worden, aber ich werde versuchen, wieder aber werde versuchen, es zu halten, so einfach wie möglich.

Ein destructor sollte in der Regel nicht verwendet werden. Es wird nur ausgeführt, .net will es auszuführen. Es wird erst nach einem Müll collectoin Zyklus laufen. Es kann eigentlich nie während des Lebenszyklus Ihrer Anwendung ausgeführt werden. Aus diesem Grunde sollten Sie nicht immer einen Code in einem destructor setzen, dass ‚müssen‘ ausgeführt werden. Sie können auch nicht auf alle vorhandenen Objekte innerhalb der Klasse verlassen, um zu existieren, wenn es läuft (sie bereits als Auftrag gereinigt worden sein, in denen Destruktoren in laufen nicht garantiert ist).

IDisposible verwendet werden soll, wenn Sie ein Objekt haben, die Ressourcen, die brauchen Reinigung (Griffe dh Datei und Grafik) erstellt. In der Tat, viele argumentieren, dass alles, was Sie in einem destructor setzen sollte putin IDisposable aufgrund der oben genannten Gründe.

Die meisten Klassen rufen entsorgen, wenn der Finalizer ausgeführt wird, aber das ist einfach dort als sicheren Schutz und sollte nie darauf verlassen. Sie sollten ausdrücklich etwas entsorgen, die IDisposable implementiert, wenn Sie mit ihm fertig sind. Wenn Sie IDisposable implementieren, sollten Sie in Finalizerthread entsorgen nennen. Siehe http://msdn.microsoft.com/en-us/library /system.idisposable.aspx für ein Beispiel.

Hier ist ein weiterer schöner Artikel, der einen Teil der Nebel rund um IDisposable, die GC aufräumt und entsorgen.

Chris Lyons WebLog Demystifying Entsorgen

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