Метод Dispose() для очистки управляемых ресурсов?

на ответ Я нашел,

очистка неуправляемых ресурсов в методе Finalize и управляемые в методе Dispose, когда шаблон Dispose / Finalize используется в вашем коде.

и это хорошая статья о finalize и dispose и получил четкое представление о них. Статья имеет следующий код (Страница 3), чтобы объяснить понятия:

class Test : IDisposable
{
    private bool isDisposed = false;

    ~Test()
    {
       Dispose(false);
    }

    protected void Dispose(bool disposing)
    {
       if (disposing)
       {
          // Code to dispose the managed resources of the class
       }
       // Code to dispose the un-managed resources of the class

       isDisposed = true;
    }

    public void Dispose()
    {
       Dispose(true);
       GC.SuppressFinalize(this);
    }
}

но ниже этого появляется та же заметка (которую я включил в начало этого вопроса).

Шаблон Dispose / Finalize Корпорация Майкрософт рекомендует реализовать как Dispose, так и Finalize при работе с неуправляемыми ресурсами. Тогда правильная последовательность будет быть для разработчика, чтобы вызвать Dispose. Завершение осуществления запустите, и ресурсы все равно будут освобождены, когда объект мусора даже если разработчик забыл вызвать Dispose метод явно. Франческо Балена пишет в своем блоге " Шаблон Dispose/Finalize должен использоваться только при вызове типа неуправляемый код, выделяющий неуправляемые ресурсы (включая неуправляемые memory) и возвращает дескриптор, который необходимо использовать для выпуска ресурс. Оба dispose и finalize должны подключаться к своему родителю объекты, вызывая соответствующие родительские методы после того, как они имеют утилизировали или доработали свои члены." проще говоря, очистка неуправляемых ресурсов в методе Finalize и управляемых в методе Dispose, когда Шаблон Dispose/Finalize использовался в коде.

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

Edit:

Как это подтвердил, что эта строка :

проще говоря, очистка неуправляемых ресурсов в методе Finalize и управляемые в методе Dispose, когда Dispose / Finalize шаблон был использован в вашем коде

ошибочно, я редактировал ответ.

2 ответов


посмотреть его очень просто.

  1. если вы имеете дело с неуправляемыми ресурсами - реализовать как Dispose и Finalize. Dispose должен быть вызван разработчиками, чтобы освободить ресурсы, как только они увидят, что это больше не нужно для них. Если они забудут позвонить Dispose затем Framework вызывает finalize в своем собственном цикле GC (обычно занимает свое собственное сладкое время).
  2. если вы не работа с неуправляемыми ресурсами- тогда ничего не делайте. Не реализуйте Finalize, ни Dispose.
  3. если ваш объект использует одноразовые объекты внутри - вы реализуете Dispose() если вы создали и сохранили ссылку на любой объект, тип которого реализует Dispose() и которые вы еще не уничтожили.

некоторые классические примеры:

System.IO.FileStream объект управляет дескрипторами блокировки / потока для файлов. Так он реализует как dispose и finalize. Если разработчик располагает его, то другая программа может получить к нему доступ сразу. Если он забывает его утилизировать, фреймворк завершает его и закрывает дескрипторы позже в своем цикле GC.

System.Text.StringBuilder доза не имеет никакого неуправляемого ресурса. Так что нет, нет.

что касается шаблона, что это значит для

// Code to dispose the managed resources of the class

это вызов методов Dispose любых объектов .NET, которые у вас есть как компоненты внутри этого класса

и

// Code to dispose the un-managed resources of the class

означает закрытие необработанных ручек и указателей. Вот ваш обновленный код с примерами

class Test : IDisposable
   {
     private bool isDisposed = false;

     ~Test()
     {
       Dispose(false);
     }

     protected void Dispose(bool disposing)
     {
       if (disposing)
       {
         // Code to dispose the managed resources of the class
         internalComponent1.Dispose();
         internalComponent2.Dispose();
       }

       // Code to dispose the un-managed resources of the class
       CloseHandle(handle);
       handle = IntPtr.Zero;   

       isDisposed = true;
     }

     public void Dispose()
     {
       Dispose(true);
       GC.SuppressFinalize(this);
     }
   }

вот старый вопрос объясняя это


если Foo имеет ресурсы, которые выиграют от детерминированной очистки, но ни один из них не может быть с пользой очищен в финализаторе, он должен реализовать IDisposable но не следует переопределять Finalize или иметь деструктор. Если класс содержит несколько ресурсов, и по крайней мере один может быть очищен в финализаторе, то каждый дискретный ресурс, который может быть очищен в финализаторе, должен быть инкапсулирован в собственный объект, оснащенный Финализатором/деструктором (который может быть определен в защищенном вложенный класс), и класс, который будет содержать эти ресурсы, должен содержать ссылки на объекты-оболочки. Как только это будет сделано, внешний класс будет соответствовать шаблону для классов с Dispose метод, но без финализатора / деструктора.