Метод 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 ответов
посмотреть его очень просто.
-
если вы имеете дело с неуправляемыми ресурсами - реализовать как
DisposeиFinalize.Disposeдолжен быть вызван разработчиками, чтобы освободить ресурсы, как только они увидят, что это больше не нужно для них. Если они забудут позвонитьDisposeзатем Framework вызывает finalize в своем собственном цикле GC (обычно занимает свое собственное сладкое время). -
если вы не работа с неуправляемыми ресурсами- тогда ничего не делайте. Не реализуйте
Finalize, ниDispose. -
если ваш объект использует одноразовые объекты внутри - вы реализуете
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 метод, но без финализатора / деструктора.