Как реализовать IDisposable правильно

Я видел так много кода C# в свое время как разработчик, которые пытаются способствовать GC путем установки переменных в NULL, или вызов Располагают () на классах (DataSet, например) в их собственных классах Располагают () метод, что я задавался вопросом, существует ли какая-либо потребность реализовать его в управляемой среде.

Действительно ли этот код является пустой тратой времени в своем шаблоне разработки?

class MyClass : IDisposable 
{
    #region IDisposable Members

    public void Dispose() 
    {
        otherVariable = null;
        if (dataSet != null)
        {
            dataSet.Dispose();
        }
    }

    #endregion
}
10
задан psych 18 July 2012 в 12:45
поделиться

3 ответа

Нет, методы удаления - не пустая трата времени.

Шаблон удаления позволяет вызывающему объекту очистить класс сразу после его завершения, а не ждать, пока сборщик мусора его заберет. Задержка не имеет большого значения для простой памяти в виде кучи, поэтому базовые классы, такие как String , не реализуют ее. Однако Dispose полезен для очистки неуправляемых ресурсов. Где-то внутри класс Dataset использует неуправляемый ресурс, поэтому он предоставляет метод удаления, позволяющий сообщить ему, когда этот неуправляемый ресурс может быть освобожден.

Если шаблон соблюдался правильно, набор данных также будет иметь финализатор (или какой-то подкласс), что означает, что если вы не удалили его вручную, в конечном итоге GC будет запущен, будет вызван финализатор и неуправляемый ресурс будут очищены таким образом. Однако этот неуправляемый ресурс может быть важен. Представьте, что если бы это была блокировка файла или подключение к базе данных, вы действительно не хотите ждать, пока запустится сборщик мусора, прежде чем вы сможете повторно использовать подключение к базе данных. Dispose предоставляет детерминированный способ очистки ресурсов, когда они завершены, вместо того, чтобы полагаться на недетерминированный сборщик мусора.

Что касается установки переменных на null в методе удаления. Почти во всех случаях это было бы бессмысленно.установка для переменной значения null удаляет ссылку на эту переменную, что делает ее подходящей для сборки мусора (если это последняя ссылка), но, поскольку вы все равно удаляете класс, вы, вероятно, выйдете за пределы области действия, содержащего class, поэтому внутренний класс в любом случае получит право на сбор.

Если у вас есть переменные-члены внутри вашего класса, которые являются одноразовыми, которые вы создали (а не только ссылки, которые вы держите), вы всегда должны вызывать для них dispose из метода dispose вашего собственного класса, но не утруждайте себя установкой для них значения null.

6
ответ дан 3 December 2019 в 20:03
поделиться

GC не вызывает .Dispose () (Однако он вызывает метод finalize ~ MyClass () , который можно предоставить вызов метода Dispose () для автоматического управления ресурсами, когда сборщик мусора решает очистить ваш класс).

Вы всегда должны предоставлять способ избавления от внутренних ресурсов, таких как DataSets , для кода, который использует ваши классы (и убедитесь, что вы действительно вызываете .Dispose () или заключите конструктор в с использованием ). Настоятельно рекомендуется использовать IDisposable в ваших классах, которые используют внутренние ресурсы.

Из MSDN :

Основное использование этого интерфейса - для освобождения неуправляемых ресурсов. Сборщик мусора автоматически освобождает память, выделенную для управляемого объекта , когда этот объект больше не используется. Однако невозможно предсказать, когда произойдет сбор мусора. Более того, сборщик мусора не знает о неуправляемых ресурсах, таких как дескрипторы окон или открытые файлы и потоки.

public void Dispose()
{
    otherVariable = null;
    if (dataSet != null)
    {
        dataSet.Dispose();
        dataSet = null;
    }
}
11
ответ дан 3 December 2019 в 20:03
поделиться

Не совсем. Если у вас есть одноразовые переменные-члены, вам, вероятно, следует избавиться от них таким образом. Ваш объект может жить дольше, чем объем выполняемой им работы, поскольку сборщик мусора не гарантированно запускается в любое конкретное время.

Установка управляемых переменных в null - пустая трата времени. Объект не получит GC быстрее.

2
ответ дан 3 December 2019 в 20:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: