Szukaj…


Uwagi

Aplikacje krytyczne pod względem wydajności w zarządzanych aplikacjach .NET mogą mieć poważny wpływ na GC. Po uruchomieniu GC wszystkie pozostałe wątki są zawieszane, dopóki się nie zakończy. Z tego powodu zaleca się staranną ocenę procesów GC i ustalenie, jak zminimalizować ich działanie.

Niezarządzane zasoby

Kiedy mówimy o GC i „stercie”, naprawdę mówimy o tak zwanej sterowanej stercie . Obiekty na zarządzanej stercie mogą uzyskiwać dostęp do zasobów, które nie znajdują się na sterowanej stercie, na przykład podczas zapisu lub odczytu z pliku. Nieoczekiwane zachowanie może wystąpić, gdy plik zostanie otwarty do odczytu, a następnie wystąpi wyjątek, uniemożliwiający zamknięcie uchwytu pliku w normalny sposób. Z tego powodu .NET wymaga, aby niezarządzane zasoby implementowały interfejs IDisposable . Ten interfejs ma jedną metodę o nazwie Dispose bez parametrów:

public interface IDisposable
{
    Dispose();
} 

Podczas obsługi niezarządzanych zasobów należy upewnić się, że są one odpowiednio usuwane. Możesz to zrobić, wywołując jawnie funkcję Dispose() w bloku na finally lub za using instrukcji using .

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

lub

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

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

Ta ostatnia jest preferowaną metodą i jest automatycznie rozszerzana do pierwszej podczas kompilacji.

Używaj SafeHandle podczas pakowania niezarządzanych zasobów

Pisząc opakowania dla niezarządzanych zasobów, powinieneś SafeHandle zamiast próbować samodzielnie wdrożyć IDisposable i finalizator. Twoja podklasa SafeHandle powinna być tak mała i prosta, jak to możliwe, aby zminimalizować ryzyko wycieku uchwytu. Prawdopodobnie oznacza to, że twoja implementacja SafeHandle byłaby wewnętrznym szczegółem implementacji klasy, która ją otacza, zapewniając użyteczny interfejs API. Ta klasa zapewnia, że nawet jeśli program SafeHandle instancji SafeHandle , niezarządzany uchwyt zostanie zwolniony.

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;
    }
}

Oświadczenie: Ten przykład jest próbą pokazania, jak chronić zarządzany zasób za pomocą SafeHandle który implementuje IDisposable i odpowiednio konfiguruje finalizatory. Przypisywanie fragmentu pamięci w ten sposób jest bardzo przemyślane i prawdopodobnie nie ma sensu.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow