Хотел бы спросить про такой паттерн использования 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;
}
Я не вижу недостатков в смысле производительности. Единственный недостаток — IDisposable должен быть идемпотентен, то есть должно быть возможно вызвать Dispose дважды. У вас это на текущий момент приведёт к двойному освобождению памяти, так что имеет смысл завести ещё и флаг isDisposed.
Даже если вы в вашем коде пользуетесь using, всё равно клиент может в любой момент вызвать GC.ReRegisterForFinalize, что приведёт к вызову Finalize даже после Dispose.
(Большой обзор, посвящённый реализации IDisposable, включающий заготовку для кастомной обёртки, тут.)
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости