Формализованный шаблон освобождения ресурсов

Формализованный шаблон освобождения ресурсов

Текущая реализация MyResourceWrapper работает вполне приемлемо, но некоторые недостатки она все же имеет. Во-первых, каждому из методов Finalize() и Dispose() приходится очищать одни и те же неуправляемые ресурсы. Это, конечно, ведет к дублированию программного кода, что усложняет задачу его поддержки. Лучше всего определить приватную вспомогательную функцию, которая вызывалась бы каждым из двух этих методов.

Далее, следует убедиться в том, что метод Finalize() не пытается освободить управляемые объекты, которые должны обрабатываться методом Dispose(). Наконец, желательно гарантировать, что пользователь объекта сможет многократно вызывать метод Disposed без появления сообщений об ошибке. В настоящий момент наш метод Dispose() таких гарантий не дает.

Для решения указанных проблемы Microsoft определила формализованный шаблон для освобождения ресурсов, устанавливающий баланс между устойчивостью к ошибкам, производительностью и простотой поддержки. Вот окончательная (и аннотированная) версия MyResourceWrapper, для которой используется этот "официальный" шаблон.

public class MyResourceWrapper: IDisposable {

 // Используется для того, чтобы выяснить,

 // вызывался ли метод Dispose().

 private bool disposed = false;

 public void Dispose() {

  // Вызов нашего вспомогательного метода.

  // Значение "true" указывает на то, что

  // очистку инициировал пользователь объекта.

  CleanUp(true);

  // Запрет финализации.

  GC.SuppressFinalize(this);

 }

 private void CleanUp(bool disposing) {

  // Убедимся, что ресурсы еще не освобождены.

  if (!this.disposed) {

   // Если disposing равно true, освободить

   // все управляемые ресурсы.

   if (disposing) {

    // Освобождение управляемых ресурсов.

   }

   // Освобождение неуправляемых ресурсов.

  }

  disposed = true;

 }

 ~MyResourceWrapper() {

  // Вызов нашего вспомогательного метода.

  // Значение "false" указывает на то, что

  // очистку инициировал сборщик мусора.

  CleanDp(false);

 }

}

Обратите внимание на то, что теперь MyResourceWrapper определяет приватный вспомогательный метод, с именем Cleanup(). Если для его аргумента указано true (истина), это значит, что сборку мусора инициировал пользователь объекта. И тогда мы должны освободить и управляемые, и неуправляемые ресурсы. Но если "уборка" инициирована сборщиком мусора, то при вызове CleanUp() следует указать false (ложь), чтобы внутренние объекты не освобождались (поскольку мы не можем гарантировать, что они все еще находятся в памяти). Наконец, перед выходом из CleanUp() член-переменная disposed логического типа устанавливается равной true, чтобы Dispose() можно было вызывать многократно без появления сообщений об ошибках.

Исходный код. Проект FinalizableDisposableClass размещен в подкаталоге, соответствующем главе 5.

На этом наше обсуждение того, как среда CLR управляет объектами с помощью сборки мусора, завершается. Остались нерассмотренными еще ряд вопросов, связанных с процессом сборки мусора (это, например, слабые ссылки и восстановление объектов), но вы теперь имеете достаточно знаний для того, чтобы продолжить исследование данной темы самостоятельно в удобное для вас время.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Улучшаем шаблон

Из книги Разгони свой сайт автора Мациевский Николай

Улучшаем шаблон Этот шаблон можно немного видоизменить, чтобы он обрабатывался не по завершению процесса, а в ходе его исполнения. Это нам очень поможет при использовании индикатора состояния:function doSomething (progressFn [, дополнительные аргументы]) {// Выполняем инициализацию(function


4.2.5. Значение освобождения

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

4.2.5. Значение освобождения В начале данной книги упоминалась ссылка на Дзэн об "особой передаче знаний вне священного писания". Не следует рассматривать ее как экзотическую, использованную ради стилистического эффекта. Основные понятия Unix всегда отличались свободной,


Массивы – шаблон CArray

Из книги Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT автора Фролов Александр Вячеславович

Массивы – шаблон CArray Библиотека MFC включает классы для организации массивов байт, слов, двойных слов, указателей, объектов класса CString и указателей на объекты класса CObject. В MFC версии 4.0 добавлен шаблон класса массива, позволяющий создавать на его основе собственные


Списки – шаблон CList

Из книги Феномен науки. Кибернетический подход к эволюции автора Турчин Валентин Фёдорович

Списки – шаблон CList В состав MFC входят классы, предназначенные для организации двунаправленных списков указателей, строк, состоящих из объектов CString, указателей на объекты класса CObject. В MFC версии 4.0 добавлен шаблон класса списка CList. С помощью этого шаблона можно создавать


Словари – шаблон CMap

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

Словари – шаблон CMap Словарь, это таблица переменной длины, состоящая из двух колонок. Первая колонка содержит ключевые поля, а вторая – соответствующие им значения. Пользуясь объектами этого класса, вы можете по ключевому полю получить связанное с ним значение. Для


4.2.5. Значение освобождения

Из книги Стандарты программирования на С++. 101 правило и рекомендация автора Александреску Андрей

4.2.5. Значение освобождения В начале данной книги упоминалась ссылка на Дзэн об "особой передаче знаний вне священного писания". Не следует рассматривать ее как экзотическую, использованную ради стилистического эффекта. Основные понятия Unix всегда отличались свободной,


Механизм освобождения

Из книги QNX/UNIX [Анатомия параллелизма] автора Цилюрик Олег Иванович

Механизм освобождения Другой важной процедурой класса MEMORY является dispose (не путайте с тезкой Pascal, которая освобождает память). Она связана с важной практической проблемой, иногда называемой финалом или окончательным завершением (finalization). Если сборщик мусора утилизирует


51. Деструкторы, функции освобождения ресурсов и обмена не ошибаются

Из книги iOS. Приемы программирования автора Нахавандипур Вандад

51. Деструкторы, функции освобождения ресурсов и обмена не ошибаются РезюмеВсе запуски этих функций должны быть успешными. Никогда не позволяйте ошибке выйти за пределы деструктора, функции освобождения ресурса (например, оператора delete) или функции обмена. В частности,


60. Избегайте выделения и освобождения памяти в разных модулях

Из книги Готовимся к пенсии: осваиваем Интернет автора Ахметзянова Валентина Александровна

60. Избегайте выделения и освобождения памяти в разных модулях РезюмеЗолотое правило программиста — положи, где взял. Выделение памяти в одном модуле, а освобождение в другом делает программу более хрупкой, создавая тонкую дальнюю зависимость между этими модулями. Такие


Операции освобождения

Из книги C++ для начинающих автора Липпман Стенли

Операции освобождения int sem_post(sem_t* sem);Эта операция увеличивает на единицу (инкремент) внутренний счетчик семафора, и в этом она диаметрально противоположна операции блокировки. Если перед этим значение счетчика семафора было равно 0, то один из потоков, ожидающих


13.7. Получение ресурсов из библиотеки ресурсов

Из книги автора

13.7. Получение ресурсов из библиотеки ресурсов Постановка задачи Требуется получить фотографии или видео непосредственно из библиотеки фотографий, не прибегая к использованию каких-либо встроенных компонентов графического пользовательского


Создаем свой шаблон

Из книги автора

Создаем свой шаблон Пояснение Не хочу грузить вас специальной терминологией, но считаю своим долгом пояснить, что то, в чем мы сейчас начинаем разбираться, называется основами языка гипертекстовой разметки, или HTML (HyperText Markup Language), если по-английски. Вот с помощью тегов —


Добавляем в шаблон текст

Из книги автора

Добавляем в шаблон текст Итак, изменим содержимое нашего шаблона, вставив туда немного текста (листинг П1.4). Ну и сохраним этот файл, например, под именем, соответствующим номеру листинга: listing_1.4.html. Открываем файл и видим следующую картину (рис. П1.9). Рис. П1.9. Файл listing_1.4.html


8.4.2. Шаблон auto_ptr А

Из книги автора

8.4.2. Шаблон auto_ptr А В стандартной библиотеке С++ auto_ptr является шаблоном класса, призванным помочь программистам в манипулировании объектами, которые создаются посредством оператора new. (К сожалению, подобного шаблона для манипулирования динамическими массивами нет.


16.13. Шаблон класса Array

Из книги автора

16.13. Шаблон класса Array В этом разделе мы завершим реализацию шаблона класса Array, введенного в разделе 2.5 (этот шаблон будет распространен на одиночное наследование в разделе 18.3 и на множественное наследование в разделе 18.6). Так выглядит полный заголовочный файл:#ifndef ARRAY_H#define