Поиск…


замечания

Процессы, зависящие от производительности в управляемых приложениях .NET, могут серьезно пострадать от GC. Когда GC работает, все остальные потоки приостанавливаются до завершения. По этой причине рекомендуется тщательно оценить процессы ГХ и определить, как свести к минимуму при ее запуске.

Неуправляемые ресурсы

Когда мы говорим о GC и «куче», мы действительно говорим о том, что называется управляемой кучей . Объекты в управляемой куче могут обращаться к ресурсам не на управляемой куче, например, при записи или чтении из файла. Неожиданное поведение может возникать, когда файл открывается для чтения, а затем возникает исключение, предотвращая закрытие дескриптора файла, как обычно. По этой причине .NET требует, чтобы неуправляемые ресурсы реализовали интерфейс IDisposable . Этот интерфейс имеет один метод Dispose без параметров:

public interface IDisposable
{
    Dispose();
} 

При работе с неуправляемыми ресурсами вы должны убедиться, что они правильно настроены. Вы можете сделать это, явно вызвав Dispose() в блоке finally или с using оператора using .

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

или же

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

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

Последний является предпочтительным методом и автоматически расширяется до первого во время компиляции.

Использовать SafeHandle при обертке неуправляемых ресурсов

При написании оберток для неуправляемых ресурсов вы должны подклассифицировать SafeHandle а не пытаться самостоятельно реализовать IDisposable и финализатор. Подкласс SafeHandle должен быть как можно более малым и простым, чтобы свести к минимуму вероятность утечки рукоятки. Вероятно, это означает, что ваша реализация SafeHandle будет внутренней деталью реализации класса, который обертывает его, чтобы предоставить полезный API. Этот класс гарантирует, что даже если программа утечки вашего экземпляра 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;
    }
}

Отказ от ответственности. Этот пример представляет собой попытку показать, как защитить управляемый ресурс с помощью SafeHandle который реализует IDisposable для вас и соответствующим образом настраивает финализаторы. Это очень надуманно и, вероятно, бессмысленно выделять кусок памяти таким образом.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow