Ich habe eine Hilfsmethode geschrieben,
%Vor% Was ein struct
kostet und gibt mir IntPtr
zurück. Ich benutze es als solches:
Das Problem ist, dass ich nur das IntPtr
für einen Bruchteil einer Sekunde brauche, damit ich es an die C DLL weitergeben kann,
Ich möchte nicht wirklich befürchten müssen, es zu befreien; Ansonsten wächst meine 1-Zeilen-Funktion auf 6:
%Vor%Gibt es einen besseren Weg, dies zu tun? Wird C # schließlich den Speicher löschen, den er zugewiesen hat?
Wenn nicht, gibt es eine Möglichkeit, den Aufruf an SDL.RenderCopy
in einigen using
-Anweisungen zu hängen, so dass ich nicht all diese temporäre Variable + explizit nonsense freigeben muss?
Ja, C # wird nicht automatisch den von Marshal.AllocHGlobal
zugewiesenen Speicher freigeben. Dieser Speicher muss mit einem Aufruf von Marshal.FreeHGlobal
freigegeben werden, andernfalls wird er geleakt.
Sie könnten einen intelligenten Zeiger erstellen, um die IntPtr
Mit diesem Wrapper können Sie den Speicher entweder manuell freigeben, indem Sie das Objekt in eine using
-Anweisung einschließen oder indem Sie zulassen, dass das Objekt freigegeben wird, wenn der Finalizer ausgeführt wird.
Viele Leute wissen das nicht (und deshalb haben Sie so viele Antworten, dass Sie nicht sagen können), aber .NET ist nur für solche Dinge eingebaut: SafeHandle .
Tatsächlich ist die .NET 2.0-Seite für eine der abgeleiteten Klassen hat ein Beispiel mit AllocHGlobal
. Wenn der Finalizer von SafeUnmanagedMemoryHandle
aufgerufen wird, ruft er automatisch FreeHGlobal
für dich auf. (Wenn Sie eine deterministische Bereinigung wünschen, anstatt nur darauf zu warten, dass der Finalizer darauf zugreift, müssen Sie entweder Close()
oder Dispose()
explizit aufrufen.)
Es dauert nur ein paar Code-Änderungen auf Ihrer Seite:
%Vor% Sobald du das tust, wird dein original Copy
Beispiel genau so funktionieren, wie du es erwartet hast.
Wenn die beiden Zeiger den Gültigkeitsbereich verlassen und abgeschlossen sind, werden sie anschließend bereinigt. Ich weiß nicht, wie _ptr
verwendet wird oder ob Texture
eine Klasse ist, die du kontrollierst, aber diese könnten möglicherweise auch auf SafeHandle
s gesetzt werden.
UPDATE: Wenn Sie mehr über den Umgang mit nicht verwalteten Ressourcen erfahren möchten (und ein Beispiel für ein besseres Muster für die Implementierung von IDisposable
erhalten, als das Beispiel der MSDN) Ich empfehle den Artikel " IDisposable: Was deine Mutter dir nie gesagt hat Über Resource Deallocation "von Stephen Cleary . Er geht in die Tiefe, wie man seine eigenen SafeHandles richtig in den Artikel schreibt.
ANHANG
Hier ist eine Kopie des Beispiels für den Fall, dass die Verbindung jemals tot wird:
%Vor%Ja, du musst es befreien, und die Art, wie du es bekommen hast, als dein 6-Zeilen-Programm ist ziemlich effizient. Es ist der Kompromiss, den Sie machen, wenn Sie den Müllsammler verlassen.
Leider gibt es dafür keine automatische Methode. Wenn Sie AllocHGlobal
aufrufen, müssen Sie explizit damit angeben FreeHGlobal
(es sei denn, Sie sind mit potenziell massivem Speicher zufrieden Lecks).
Dieser Speicher muss mithilfe der
Marshal.FreeHGlobal
Methode.
Was ich in der Vergangenheit getan habe, ist, meine AllocHGlobal
-Zuordnungen in einer IDisposable
-Wrapper-Klasse einzupacken, wobei Dispose()
auf dem Zeiger FreeHGlobal
aufruft. Auf diese Weise konnte ich sie in eine using
-Anweisung einfügen.