Best practices für das handling von IDisposable
Ich habe eine Klassen-Hierarchie, jedes Mitglied kann erstellen IDisposable
Objekte.
Habe ich ein List<IDisposable>
- Eigenschaft der Basisklasse dieser Hierarchie, zu denen ich hinzufügen keine Einweg-Objekte bei der Erstellung. Die Wurzel Dispose
Methode iteriert durch die Liste und ruft Dispose
für jedes Element in der Liste und löscht die Liste. In der Anwendung, die ich ausdrücklich nennen das top-Objekt ist Dispose
Methode, wodurch die Entsorgung Kaskade durch die Hierarchie.
Dies funktioniert, aber gibt es einen besseren Weg? Bin ich unwissentlich duplizieren einige Funktionen, die schon in den Rahmen?
(Hinweis - die fraglichen Objekte haben eine Lebensdauer, die verhindert nur, wickelte Sie in ein using
block oder Entsorgung von Ihnen in der gleichen methodwhere Sie erstellt werden.)
Bearbeiten
Nur zur Klarstellung - ich bin nur halten diese Objekte herum, die beibehalten werden müssen. Einige entsorgt werden, in der gleichen Methode, wo Sie erstellt werden, aber viele sind in einer Weise verwendet werden, dass dies nicht möglich ist.
IDisposable
s?Ich bin die Schaffung und Aufrechterhaltung einer Menge von nicht verwalteten Ressourcen - Bilder, usw. -, die aktualisiert werden out-of-band von nicht verwaltetem code.
InformationsquelleAutor 3Dave | 2011-09-04
Du musst angemeldet sein, um einen Kommentar abzugeben.
So lange wie implementieren Sie das dispose-Muster richtig (wie beschrieben hier), diese Methode ist gut.
Soweit ich weiß, nur
using
Aussagen haben spezielle Unterstützung fürIDisposable
- es gibt nichts, in das framework, das repliziert, was Sie tun.InformationsquelleAutor Oded
Nein, dass ist korrekt.
IDisposable
ist entworfen, um frei nicht verwalteten Ressourcen und genannt werden sollte, so bald wie möglich, nachdem Sie fertig mit der Instanz. Es ist ein verbreiteter Irrtum, dass dies unnötig ist, oder dass die finailizer wird dies automatisch tun, wenn das Objekt von der garbage Collection eingesammelt. Tut es aber nicht.Dem richtigen Muster für
IDisposable
ist hier und unten aufgeführt für eine schnelle Referenz.Dispose()
auf den Inhaber, die wiederum ruftDispose()
auf alle seine Kinder. Was ist nicht korrekt? Und es ist kein Hinweis auf etwaige Missverständnisse, die in der Frage, denke ich.Es war ein Tippfehler - es liest
no that is correct
.Ich denke, @Oded schlagen Sie es um etwa 45 Sekunden, aber +1 für das Codebeispiel.
Ja, immer der Letzte - gotta-Typ schneller 🙂
InformationsquelleAutor TheCodeKing
Wenn du redest beliebigen
IDisposable
Objekte, ich glaube nicht, dass es existiert.Den
System.ComponentModel.Container
Klasse implementiert cascading Entsorgen, sondern erfordert die Elemente zu implementierenIComponent
. Wenn Sie Steuern IhreIDisposable
Objekte könnten Sie die UmsetzungIComponent
- es erfordert nur die Implementierung einer einzigen EigenschaftSite
zurückkehren könnennull
.IComponent
- Schnittstelle ist nur für nicht-visuelle Komponenten gedacht, die in einen RAD-designer, die scheint unwahrscheinlich, dass in einer Allgemeinen Klasse Hierarchie.Ich habe darauf hingewiesen, seine Existenz, anstatt es zu empfehlen für ein bestimmtes Szenario. Aber wenn Sie nicht denken, es ist eine gute Idee, vielleicht könnten Sie erklären, warum?
Gute info. Ich sollte erwähnt haben, dass einige dieser läuft auf dem kompakten Rahmen, in dem IComponent scheint nicht unterstützt zu werden.
Wie gesagt, die Umsetzung
IComponent
zeigt an, dass das Objekt kann verwendet werden in einer RAD-designer (D. H. niedriger als eine Komponente auf einem windows form) und den damit verbundenen design-time-Unterstützung für dieses Szenario. Das ist wahrscheinlich nicht der Fall für die meisten Klasse-Hierarchien. Gelesen von msdn.microsoft.com/en-us/library/0b1dk63b.aspx und die verlinkten Seiten für weitere Informationen.nützlich ist diese info, da es hilft, zu beurteilen, ob die Empfehlung gilt für ein bestimmtes Szenario. In diesem Fall bin ich noch nicht überzeugt - thare sind IComponent-Klassen in das Framework, dass nicht in Erster Linie für den Einsatz in einer RAD-designer - z.B. System.Diagnostik.Prozess.
InformationsquelleAutor Joe
Klingt wie eine situation, wo der Besucher Muster angebracht sein könnte. Obwohl ich nie verstehen, die behaupten, dass es erstreckt Ihren Klassen und lässt Sie unverändert, denn ich kenne nur Beispiele, in denen die Klassen sollten eine
AcceptVisitor
- Methode oder dergleichen. BTW, es ist nicht ein Muster, das ich mag, weil es Komplex ist und dazu neigt, Unordnung code.InformationsquelleAutor Gert Arnold
Wenn ein Objekt viele andere IDisposable-Objekten und pflegen das Eigentum von Ihnen in seiner Existenz, die Muster, die Sie beschreiben, kann eine gute sein. Es kann erhöht werden, indem die mit Ihrer Klasse implementieren die Methode "T RegDispos<T>(T) where T:IDisposable;" die eine Einweg-zu der Liste und gibt es zurück. Man kann somit kümmern sich um die Erstellung und Bereinigung der eine Ressource in der gleichen Anweisung, durch den Austausch eine Aussage wie "someField = someDisposType.CreateThing();" mit "someField = RegDispos(someDisposType.CreateThing());".
Wenn Ihre Klasse nicht verfügbar, einen öffentlichen Konstruktor (erfordert Außenseiter Nutzung factory-Methoden), und wenn Sie entweder mit vb.net oder bereit sind, zu verwenden thread-statische-Felder, können Sie sogar kombinieren, Initialisierung und Bereinigung mit der Deklaration (z.B. "var someField = RegDispos(someDisposType.CreateThing());"). Für diese sicher zu sein, muss der Konstruktor aufgerufen werden, die innerhalb eines try/catch-oder try/finally-block können, rufen Sie Dispose auf die erstellten sub-Objekte, wenn der Bau scheitert. Weil Feld-Initialisierungen in C# keinen Zugriff auf Konstruktor-Parameter (eine Schwäche in der Sprache, IMHO) die einzige Möglichkeit zur Umsetzung eines solchen Musters ist eine factory-Methode erstellen der Liste und legen Sie Sie in eine thread-variable, die dann gelesen werden, indem eine statische RegDispos Methode.
InformationsquelleAutor supercat