Метод 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
метод, но без финализатора / деструктора.