2013-05-17 6 views
15

В this answer я нашел,Dispose() для очистки управляемых ресурсов?

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

И позже я нашел this nice article о завершении и утилизации и получил четкое представление о них. Изделие имеет следующий код (Page 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/Finalize должна использоваться только тогда, когда ваш тип вызывает неуправляемый код, который выделяет неуправляемые ресурсы (в том числе неуправляемую память ) и возвращает дескриптор, который вы должны использовать в конечном итоге для освобождения ресурса. распоряжаться и финализировать, должны подключиться к своим родителям объектам, вызвав соответствующие методы их родителя после того, как они удалили или завершили свои собственные члены ». Проще говоря, очистите неуправляемые ресурсы в методе Finalize и управляемых в методе Dispose, когда в вашем коде был использован шаблон Dispose/Finalize .

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

Edit:

Как было подтверждено, что эта строка:

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

является ошибочным, я редактировал this answer.

ответ

30

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

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

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

System.IO.FileStream объект управляет блокировка/поток обрабатывает к файлам. Таким образом, он реализует как утилизацию, так и завершение. Если разработчик располагает, то другая программа может сразу же получить к нему доступ. Если он забывает распоряжаться им, то Framework завершает его и закрывает дескрипторы позже в своем цикле 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); 
    } 
    } 

Вот старый вопрос explaing это http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/186947fd-e6da-41fb-9998-3b1e6223f17c

+0

На самом деле вообще нет очистки управляемых ресурсов. Я не вижу его смысла. Максимум, который вы можете сделать для очистки управляемого ресурса, - это присвоить ему значение NULL. Что совершенно не нужно с такой хорошей GC встроенной. –

+0

Thats статья, написанная в 2006 году, поэтому я бы не стал сильно беспокоиться об этом. –

+2

Это не так просто. Вы также должны реализовать 'Dispose()', если вы создали и сохранили ссылку на * любой * объект типа, который реализует 'Dispose()' и который вы еще не выбрали. Некоторые типы не используют неуправляемые ресурсы, но у них есть такие вещи, как подписки на события, которые они должны отцеплять в своих методах 'Dispose(). Вы должны распоряжаться такими объектами ДАЖЕ, ЧЕМ, они не используют неуправляемые ресурсы, иначе вы можете иметь утечку памяти. Это часто особенно справедливо для классов пользовательского интерфейса, полученных из 'Control' или' UserControl'. –

3

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

Смежные вопросы