Wann sollte IDisposable verwendet werden, ist es falsch, es zu benutzen? Was ist mit Dispose Chaining?

8

Ich suche wirklich nach Best-Practice-Weisheiten. Also hier sind die Fragen, ich werde mehr hinzufügen, wenn Leute Kommentare hinterlassen. Fühlen Sie sich frei, einige oder alle diese Fragen zu beantworten.

Wann sollte IDisposable verwendet werden? Nur wenn ich nicht verwaltete Ressourcen habe?

Welche Variationen des Entsorgungsmusters gibt es und warum variieren sie?

Welche gemeinsamen nicht verwalteten Ressourcen sollte ich beachten?

Ist es falsch oder irreführend, IDisposable zu implementieren?

Sollen Dispose-Aufrufe jemals miteinander verkettet werden, oder sollten wir uns auf Anweisungen verlassen?  Zum Beispiel:

%Vor%     
Firoso 31.07.2010, 22:32
quelle

2 Antworten

6

Wow. Viele Fragen hier!

  

Wann sollte IDisposable verwendet werden? Nur wenn ich nicht verwaltete Ressourcen habe?

IDisposable wird normalerweise verwendet, um Ressourcen zu bereinigen, aber das ist nicht unbedingt alles, wofür es gut ist. Es ist ein allgemeines Muster, um dem verbrauchten Objekt mitzuteilen, dass Sie damit fertig sind. Ein Beispiel ist ein Timer:

%Vor%

In diesem Fall gibt der Aufruf von Dispose nicht unbedingt Ressourcen frei, es ist nur eine bequeme & amp; konsistent (zwei Tasten für ein Muster!) Weg, um den Timer zu sagen "OK, ich bin fertig mit dir jetzt" und der Timer kann aufhören zu timing, und vielleicht die Zeit irgendwo aufzeichnen.

Eine weitere gute Faustregel ist, dass Sie, wenn Sie einen Finalizer benötigen, aus irgendeinem Grund in der Regel auch IDisposable -Zugriff auf die gleiche Routine bereitstellen sollten, damit die konsumierende Klasse die Klasse früher abschließen kann, anstatt auf die GC.

  

Welche Variationen des Entsorgungsmusters gibt es und warum variieren sie?

Es gibt nur einen echten "spezifischen" Typ von IDisposable Implementierung, den ich kenne - das Finalize / Dispose-Muster:

%Vor%
  

Welche gemeinsamen nicht verwalteten Ressourcen sollte ich beachten?

Alles, was IDisposable insbesondere in den .NET-Bibliotheken implementiert, sollte Handles für nicht verwaltete Ressourcen haben und sollte entsorgt werden. Normalerweise greifen Sie nur über diese auf nicht verwaltete Ressourcen zu. Wenn nicht, werden Sie es wissen - normalerweise einen Treiber oder etwas bauen.

  

Ist es falsch oder irreführend, IDisposable zu implementieren?

Es kann sinnlos sein, es zu übernutzen, aber nicht direkt schädlich.

  

Sollten Dispose-Aufrufe jemals miteinander verkettet werden

Eine Klasse sollte nur IDisposables, die sie intern erstellt, entsorgen. Wenn es verfügbare Abhängigkeiten gibt, die injiziert wurden oder außerhalb des Gültigkeitsbereichs der Klasse liegen, sollten Sie sie niemals entsorgen.

    
Rex M 31.07.2010, 22:40
quelle
3

Es gibt zwei grundlegende Dinge, die ich über IDisposable geschrieben habe, und ich empfehle Ihnen, mindestens die erste zu lesen: Wie IDisposable und Finalizer implementieren - 3 einfache Regeln (Ich habe auch andere Blog-Posts zum Thema ) und IDisposable - Was deine Mutter dir nie über Ressourcen-Allokation erzählt hat .

Wann sollte IDisposable verwendet werden? Nur wenn ich nicht verwaltete Ressourcen habe?

IDisposable sollte für eines der folgenden drei Dinge verwendet werden: Freigeben einer nicht verwalteten Ressource, Freigeben von verwalteten Ressourcen und RAII. Ich bevorzuge verschiedene Muster für diese unterschiedlichen Bedürfnisse.

Beachten Sie, dass der Rest meiner Antworten (und die Links) im Zusammenhang mit der Freigabe von Ressourcen alle IDisposable diskutieren. Sie sprechen RAII nicht an.

Welche Variationen des Entsorgungsmusters gibt es und warum variieren sie?

Das Microsoft-Muster ist das bekannteste. Es behandelt die Freigabe nicht verwalteter und verwalteter Ressourcen und ermöglicht die Vererbung. Ich bevorzuge ein einfacheres Muster, das in meinem Blog beschrieben wird ( 3 einfache Regeln ) , das ist das Muster, das Microsoft tatsächlich seit .NET 2.0 gefolgt hat.

Welche gemeinsamen nicht verwalteten Ressourcen sollte ich beachten?

Ich bevorzuge eine einzige IDisposable -Klasse für jeden Typ nicht verwalteter Ressourcen (ähnlich wie Microsofts SafeFileHandle ). Jedes Mal, wenn Sie Ihrem Programm / Ihrer Bibliothek eine Art nicht verwalteter Ressource hinzufügen, müssen Sie nur einmal damit umgehen.

Die Frage lautet dann "welche Klassen sollte ich entsorgen?", die eine einfache Antwort hat: "alle Klassen, die IDisposable implementieren."

Ist es falsch oder irreführend, IDisposable zu implementieren?

Nein. Eine leere IDisposable Implementierung ist immer eine Option. Sie sollten in Erwägung ziehen, IDisposable zu Interfaces oder Basisklassen hinzuzufügen, wenn Sie glauben, dass eine Implementierung sie verwenden kann. Dies ist ein Design-Problem, über das ich mehr in meinem Artikel Was dir deine Mutter nie erzählt hat .

Sollen Dispose-Aufrufe jemals miteinander verkettet werden oder sollten wir uns auf Anweisungen verlassen?

Es ist üblich, dass Dispose Dispose für alle Mitgliedsobjekte aufruft, die es besitzt. Sehen Sie meinen zweiten Regel Blogbeitrag für weitere Details.

    
Stephen Cleary 01.08.2010 11:30
quelle