2009-05-27 5 views
0

"Datei und Schriftart sind Beispiele für verwaltete Typen, die auf nicht verwaltete Ressourcen zugreifen (in diesem Fall Dateihandles und Gerätekontexte). Es gibt viele andere Arten von nicht verwalteten Ressourcen und Klassenbibliothekstypen, die kapseln Alle diese Typen müssen die IDisposable-Schnittstelle implementieren. Wenn Sie ein IDisposable-Objekt verwenden, sollten Sie es in der Regel in einer using-Anweisung deklarieren und instanziieren. " - MSDNListe der Fälle, in denen USING-Anweisung verwendet werden sollte

Gibt es eine Liste solcher Fälle (verwaltete Typen, die auf nicht verwaltete Ressourcen wie FILE und FONT zugreifen, ...), wo USING-Anweisung verwendet werden sollte?

Antwort

2

Immer wenn Sie eine Ressource haben, die deterministische Säuberung benötigt, d. H. Sie möchten, dass sie eine Chance hat, "zerstört" zu werden, sobald Sie damit fertig sind.

Genauer gesagt versucht die IDisposible-Schnittstelle hauptsächlich, das Fehlen eines Schlüsselwortes "löschen" in .net-Sprachen zu lösen. Da die CLR Garbage Collected ist, wissen Sie nie, wann der Finalizer (Destruktor) für ein Objekt ausgeführt wird. Es steht dem GC frei, so lange zu warten, wie es Ihnen gefällt, bevor er die verwaltete Ressource freigibt.

Viele verwaltete Ressourcen wickeln jedoch die zugrunde liegenden endlichen Ressourcen ein - Speicher ist nicht das einzige, was zugewiesen und freigegeben werden muss. Wie erwähnt, sind Dateigriffe eins; Datenbank behandelt eine andere - es gibt unzählige Beispiele. Um ein inkonsistentes Durcheinander von Aufräum-Idiomen zu vermeiden, wird das IDisposible-Muster verwendet, um zu sagen: "Bitte geben Sie Ihre endlichen Ressourcen frei, ich bin fertig mit ihnen". Da es in das Framework integriert ist, erhält es spezielle Sprachunterstützung über "using", um sicherzustellen, dass Sie nie vergessen, die Dispose-Methoden aufzurufen und somit die nicht verwaltete Ressource "auslaufen lassen".

Dies bedeutet nicht, all IDisposible Implementierer in einem mit eingewickelt werden soll - wenn Sie eine Referenz sind zu halten, und müssen sie in der Zukunft sollten Sie auf jeden Fall sie nicht wickeln, wie Sie eine vorzeitige Freigabe verursachen würden die zugrunde liegende Ressource. Rufen Sie Dispose nur auf, wenn Sie mit dem Objekt fertig sind, und schließen Sie das "Verwenden" nur dann ein, wenn Sie wissen, dass Sie damit fertig sind, nachdem das Anwendungsfenster beendet wurde.

So wie wir erwarten, brauchen Sprachen, die deterministische Zerstörung haben, wie C++/CLI, nicht "verwenden". Nicht-Heap-C++/CLI-Objekte werden mit ihrer Dispose-Methode automatisch aufgerufen, wenn sie außerhalb des Bereichs liegen und das Destruktorverhalten nachahmen, das das Muster zu erfassen versucht.

2

Nein. Der MSDN-Artikel hat Ihnen gerade gesagt, dass Sie es verwenden sollten, wenn Sie ein IDisposable Objekt verwenden. Es gibt viele Framework-Klassen, die IDisposable implementieren, und Sie werden sicher auch viele eigene definieren.

6

Jeder Typ, der IDisposable implementiert, sollte using verwenden.

aktualisieren (in Reaktion auf die Kommentare): using sollte eine Instanz eines IDisposable Typs umgeben, ist es unter der Annahme, nicht in größerem Umfang erforderlich.

+0

würde der down voter bitte einen Kommentar hinterlassen. Danke –

+0

2 downvotes und keine Kommentare. was gibt? –

+0

Angenommen, IDisposable ist eine lokale Variable. Wenn es sich um ein Klassenmitglied handelt, sollten Sie IDisposable selbst implementieren, um diese Objekte zu bereinigen. –

2

Der korrekte Ansatz ist immer die using Anweisung zu verwenden, wenn der Typ die IDisposable Schnittstelle implementiert, aber Ausnahmen der Regel kennen.Ausnahmen

bekannt:

  • Hauptform (Windows Forms-Anwendung, weil sie von der Application Klasse verwaltet wird)
  • SystemPens.*, SystemBrushes.* (diese statischen Instanzen zwischengespeichert werden intern)
  • Icons.* (diese statische Instanzen werden intern zwischengespeichert)
  • Registry.* (diese statischen Instanzen sind Cache d intern)
  • AutoResetEvent, ManualResetEvent (sollte eigentlich entsorgt werden, aber wenn Sie es tun, machen es sehr sorgfältig, wie es Rennbedingungen verursachen können)

Die Liste der bekannten Ausnahmen ist sicherlich nicht vollständig.

+0

Registry implementiert IDisposable nicht. Symbol implementiert, so dass Dispose() aufgerufen werden sollte ... –

+0

Datasets und Datatables sind verfügbar, enthalten aber keine nicht verwalteten Ressourcen. –

+0

@Joel Coehoorn: Ich denke, wenn Sie Reflect in Datasets und Datatables, der Dispose() Aufruf nichts tut. –

0

Die einfache Regel ist "jedes Mal, wenn Sie eine Ressource haben, die sofort nach der Verwendung freigegeben werden sollte, anstatt zu einem unbekannten Zeitpunkt in der Zukunft, wenn der Garbage Collector es freigibt".

Alle begrenzten Ressourcen, im Wesentlichen nicht verwaltet oder verwaltet. Dateien, Netzwerk-Sockets, Datenbankverbindungen, Registrierungs-Handles, alles, was nicht unbegrenzt herumlaufen sollte.