Следует ли использовать SuppressFinalize?

304
14 февраля 2017, 17:03

Хотел бы спросить про такой паттерн использования SuppressFinalize. Допустим, у меня имеется объект Foo, который хранит в себе какой-нибудь ресурс. Объект Foo ответственен за освобождение выделенного ресурса. Я использую всегда такой подход:

Класс Foo всегда реализует finalize и dispose методы, которые используют внутренний метод, который освобождает ресурсы. При вызове dispose я всегда вызываю SuppressFinalize метод (дабы оптимизировать процесс сборки мусора - не нужно будет хранить данный объект в очереди финализации, ну или например если я забуду явно вызвать dispose метод).

Имеет ли данный подход какие-либо performance недостатки? Не могу понять, будет ли иметь какие-либо "сайд эффекты" такой подход - например что gc всегда подобные объекты будет помещать в очередь финализации

UPDATE: Пример использования (написан на C++/Cli - флажок в CleanResources не используется потому что управляемых полей нет) И еще, я упростил немного код, вызов нативных методов обрамлен try/catch блоком, дабы оборачивать исключения в свой управляемый тип исключения

NativeWrapper::NativeWrapper(void) :
   m_native(new Native())
{
}
NativeWrapper::~NativeWrapper(void)
{
    CleanResources();
    System::GC::SuppressFinalize(this);
}
NativeWrapper::!NativeWrapper(void)
{
CleanResources();
}
void NativeWrapper::CleanResources(void)
{
    delete m_native;
}
Answer 1

Я не вижу недостатков в смысле производительности. Единственный недостаток — IDisposable должен быть идемпотентен, то есть должно быть возможно вызвать Dispose дважды. У вас это на текущий момент приведёт к двойному освобождению памяти, так что имеет смысл завести ещё и флаг isDisposed.

Даже если вы в вашем коде пользуетесь using, всё равно клиент может в любой момент вызвать GC.ReRegisterForFinalize, что приведёт к вызову Finalize даже после Dispose.

(Большой обзор, посвящённый реализации IDisposable, включающий заготовку для кастомной обёртки, тут.)

READ ALSO
Удаление строк в datagridview выделением сверху вниз и наоборот

Удаление строк в datagridview выделением сверху вниз и наоборот

Сегодня во время работы с DataGridView,заметил странную особенностьСтояла задача удаления огромного количества строк(Почти 20000) вместе,получив...

305
Парсинг JSON в DropDownList ASP.NET

Парсинг JSON в DropDownList ASP.NET

Привет есть кодКонтролер

315
Команда using()

Команда using()

Правильно ли я понял, что данная конструкция создает область видимости(работы) переменной variableИ после закрытия скобки вызывает Dispose() переменной?

272
Заполнение базы данных CodeFirst EF

Заполнение базы данных CodeFirst EF

При создании базы использую для авторизации IdentityВ файле по умолчанию IdentityModels

306