Suche…


Bemerkungen

Leistungskritische Anwendungen in verwalteten .NET-Anwendungen können durch den GC stark beeinträchtigt werden. Wenn der GC ausgeführt wird, werden alle anderen Threads bis zum Abschluss angehalten. Aus diesem Grund wird empfohlen, die GC-Prozesse sorgfältig zu bewerten und festzulegen, wie sie bei der Ausführung minimiert werden sollen.

Nicht verwaltete Ressourcen

Wenn wir über die GC und den "Heap" sprechen, sprechen wir wirklich über den sogenannten verwalteten Heap . Objekte auf dem verwalteten Heap können auf Ressourcen zugreifen, die sich nicht auf dem verwalteten Heap befinden, z. B. beim Schreiben oder Lesen aus einer Datei. Unerwartetes Verhalten kann auftreten, wenn eine Datei zum Lesen geöffnet wird und dann eine Ausnahmebedingung auftritt, die das Schließen des Datei-Handles verhindert. Aus diesem Grund erfordert .NET, dass nicht verwaltete Ressourcen die IDisposable Schnittstelle implementieren. Diese Schnittstelle verfügt über eine einzige Methode namens Dispose ohne Parameter:

public interface IDisposable
{
    Dispose();
} 

Beim Umgang mit nicht verwalteten Ressourcen sollten Sie sicherstellen, dass sie ordnungsgemäß entsorgt werden. Sie können dies tun, indem Sie Dispose() explizit in einem finally Block oder mit einer using Anweisung aufrufen.

StreamReader sr; 
string textFromFile;
string filename = "SomeFile.txt";
try 
{
    sr = new StreamReader(filename);
    textFromFile = sr.ReadToEnd();
}
finally
{
    if (sr != null) sr.Dispose();
}

oder

string textFromFile;
string filename = "SomeFile.txt";

using (StreamReader sr = new Streamreader(filename))
{
    textFromFile = sr.ReadToEnd();
}

Letzteres ist die bevorzugte Methode und wird beim Kompilieren automatisch auf das Erstere erweitert.

Verwenden Sie SafeHandle, wenn Sie nicht verwaltete Ressourcen umschließen

Wenn Sie Wrapper für nicht verwaltete Ressourcen schreiben, sollten Sie SafeHandle eher als Unterklasse SafeHandle anstatt IDisposable und einen Finalizer selbst zu implementieren. Ihre SafeHandle Unterklasse sollte so klein und einfach wie möglich sein, um die SafeHandle zu minimieren. Dies bedeutet wahrscheinlich, dass Ihre SafeHandle-Implementierung ein internes Implementierungsdetail einer Klasse enthält, das diese umschließt, um eine verwendbare API bereitzustellen. Diese Klasse stellt sicher, dass Ihr nicht verwalteter Handle freigegeben wird, auch wenn ein Programm Ihre SafeHandle Instanz SafeHandle .

using System.Runtime.InteropServices;

class MyHandle : SafeHandle
{
    public override bool IsInvalid => handle == IntPtr.Zero;
    public MyHandle() : base(IntPtr.Zero, true)
    { }

    public MyHandle(int length) : this()
    {
        SetHandle(Marshal.AllocHGlobal(length));
    }

    protected override bool ReleaseHandle()
    {
        Marshal.FreeHGlobal(handle);
        return true;
    }
}

Haftungsausschluss: In diesem Beispiel wird gezeigt, wie eine verwaltete Ressource mit SafeHandle die IDisposable für Sie implementiert und die Finalizer entsprechend konfiguriert. Es ist sehr verständlich und wahrscheinlich sinnlos, auf diese Weise einen Speicherplatz zuzuweisen.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow