Der Punkt dieser beiden Strukturen besteht darin, zu verhindern, dass der Garbage Collector eine Ressource freigibt und das Handle ungültig macht, bevor der P / Invoke-Aufruf beendet wurde. Die von Ihnen verknüpfte Dokumentation weist darauf hin, dass es sich um spezielle Typen handelt, die vom Interop-Marshaller erkannt werden.
Was ich aus der Dokumentation entnehme, ist, dass HandleRef
im Wesentlichen ein Sonderfall der allgemeineren GCHandle
Struktur ist.
Die HandleRef
-Struktur ist speziell für das Wrappen von Handles auf nicht verwaltete Ressourcen vorgesehen, die mit P / Invoke-Code verwendet werden. Zum Beispiel Fenstergriffe ( HWND
) oder Gerätekontexte ( HDC
). Es hat eine Eigenschaft Handle
, die einen Wert vom Typ IntPtr
zurückgibt, der ein ganzzahliger Wert ist, der die Größe eines Zeigers auf der Architektur des zugrunde liegenden Systems hat. Sie können dies verwenden, um schnell & amp; Erhalte leicht den Griff, den er umschließt.
Während die GCHandle
-Struktur es erlaubt, den Typ des Handles anzugeben, den sie mit einem der Mitglieder der GCHandleType
-Enumeration umschließt, wurde die HandleRef
-Struktur speziell entwickelt, um Handles in nicht verwaltete Ressourcen zu integrieren. Sie würden wahrscheinlich die GCHandle
-Struktur verwenden, wenn Sie direkt mit nicht verwaltetem Speicher arbeiten und nicht mit den speziellen Handles, die die Win32-API als schwarze Felder behandelt.
Es ist nicht notwendig, beides zu verwenden. Man kann einfach GC.KeepAlive
aufrufen, damit der Garbage Collector die Ressource nicht vorzeitig freigibt.
Und das ist wahrscheinlich auch nicht nötig. Ich schreibe P / Invoke-Code seit Jahren, und ich habe festgestellt, dass, wenn es richtig geschrieben ist, keine dieser Strukturen erforderlich ist. Wenn ein Klassenobjekt während des API-Aufrufs während der Ausführung von Garbage Collections gesammelt wird, handelt es sich um einen Fehler in Ihrer Anwendung. Ich möchte eigentlich über eine Ausnahme benachrichtigt werden, den Fehler nicht zu verbergen.
Ein Unterschied ist in dem Link angegeben, den Sie erwähnt haben:
Der HandleRef-Werttyp ist wie GCHandle ein spezieller erkannter Typ durch den Interop Marshaller. Eine normale, nicht gepinnte GCHandle verhindert ebenfalls vorzeitige Garbage Collection, aber HandleRef bietet bessere Performance. Obwohl Sie HandleRef verwenden, um ein Objekt am Leben zu erhalten Die Dauer eines Anrufs auf der Plattform ist vorzuziehen. Sie können auch GC.KeepAlive-Methode für den gleichen Zweck.
Tags und Links .net c# com-interop marshalling