Die System.Runtime.InteropServices.SafeHandle ist eine abstrakte Basisklasse. Abgeleitete Klassen stellen bestimmte Instanzen für verschiedene Handletypen bereit. Diese abgeleiteten Klassen überprüfen, welche Werte für das System.IntPtr als ungültig gelten und wie das Handle tatsächlich frei wird. SafeFileHandle leitet beispielsweise von SafeHandle ab, um IntPtrs zu umschließen, die geöffnete Dateihandles/Deskriptoren identifizieren, und überschreibt die SafeHandle.ReleaseHandle()-Methode, um sie zu schließen (über die Close-Funktion unter Unix oder CloseHandle-Funktion unter Windows). Die meisten APIs in .NET-Bibliotheken, die eine nicht verwaltete Ressource erstellen, umschließen sie in einem SafeHandle und geben das SafeHandle bei Bedarf an Sie zurück, anstatt den Rohzeiger zurückzugeben. In Situationen, in denen Sie mit einer nicht verwalteten Komponente interagieren und einen IntPtr für eine nicht verwaltete Ressource erhalten, können Sie Einen eigenen SafeHandle-Typ erstellen, um sie umzuschließen. Daher müssen nur wenige Nicht-SafeHandle-Typen Finalizer implementieren. Die meisten Einweg-Musterimplementierungen werden nur mit anderen verwalteten Ressourcen verpackt, von denen einige SafeHandles sein können. Der .NET-Garbage Collector weist keinen nicht verwalteten Speicher zu oder gibt ihn frei. Das Muster zum Entsorgen eines Objekts, das als Dispose-Muster bezeichnet wird, ordnet die Lebensdauer eines Objekts an. Das dispose-Muster wird für Objekte verwendet, die die IDisposable-Schnittstelle implementieren, und ist häufig bei der Interaktion mit Datei- und Pipe-Handles, Registrierungshandles, Wartehandles oder Zeigern auf Blöcke von nicht verwaltetem Speicher.

Dies liegt daran, dass der Garbage Collector nicht verwaltete Objekte nicht zurückfordern kann. Stricken Sie diese Damen Longline Jacke von Rowan Knitting & Crochet Magazine Nummer 65, ein Design von Martin Storey mit unserem atemberaubenden Garn mit einem weichen Griff, Softyak DK (Baumwolle, Yak und Nylon.) Diese gemütliche Strickjacke ist mit einer Kabelplatte umrandet und das Muster ist für den erfahreneren Stricker geeignet. Wenn der Methodenaufruf von einem Finalizer stammt, sollte nur der Code ausgeführt werden, der nicht verwaltete Ressourcen freigibt. Der Implementierer ist dafür verantwortlich, sicherzustellen, dass der falsche Pfad nicht mit verwalteten Objekten interagiert, die möglicherweise freigegeben wurden. Dies ist wichtig, da die Reihenfolge, in der der Garbage Collector verwaltete Objekte während der Finalisierung zerstört, nicht deterministisch ist. Verwaltete Objekte, die große Mengen an Arbeitsspeicher oder knappe Ressourcen verbrauchen. Weisen Sie große verwaltete Objektverweise null zu, damit sie wahrscheinlicher nicht erreichbar sind. Dadurch werden sie schneller freigegeben, als wenn sie nicht deterministisch zurückgefordert würden. Das folgende Beispiel veranschaulicht das Dispose-Muster für eine Basisklasse, DisposableStreamResource, die ein sicheres Handle zum Kapseln nicht verwalteter Ressourcen verwendet. Es definiert eine DisposableStreamResource-Klasse, die ein SafeFileHandle verwendet, um ein Stream-Objekt umzuschließen, das eine geöffnete Datei darstellt.

Die Klasse enthält auch eine einzelne Eigenschaft, Size, die die Gesamtzahl der Bytes im Dateistream zurückgibt. Das folgende Beispiel veranschaulicht das dispose-Muster für eine abgeleitete Klasse, DisposableStreamResource2, die von der Imwegsbeispiel vorgestellten DisposableStreamResource-Klasse erbt. Die Klasse fügt eine zusätzliche Methode hinzu, WriteFileInfo, und verwendet ein SafeFileHandle-Objekt, um das Handle der beschreibbaren Datei umzuschließen. Im vorherigen Beispiel wird ein SafeFileHandle-Objekt verwendet, um das Muster zu veranschaulichen. Jedes von SafeHandle abgeleitete Objekt kann stattdessen verwendet werden. Beachten Sie, dass das SafeFileHandle-Objekt im Beispiel nicht ordnungsgemäß instanziiert. Alle nicht versiegelten Klassen oder (Visual Basic-Klassen, die nicht als NotInheritable geändert wurden) sollten als potenzielle Basisklasse betrachtet werden, da sie vererbt werden könnten. Wenn Sie das dispose-Muster für eine potenzielle Basisklasse implementieren, müssen Sie Folgendes bereitstellen: Es ist möglich, dass eine Basisklasse nur auf verwaltete Objekte verweist und das dispose-Muster implementiert.

Liked it? Take a second to support frostclaw on Patreon!