Шрифт:
Далее, следует убедиться в том, что метод Finalize не пытается освободить управляемые объекты, которые должны обрабатываться методом Dispose. Наконец, желательно гарантировать, что пользователь объекта сможет многократно вызывать метод Disposed без появления сообщений об ошибке. В настоящий момент наш метод Dispose таких гарантий не дает.
Для решения указанных проблемы Microsoft определила формализованный шаблон для освобождения ресурсов, устанавливающий баланс между устойчивостью к ошибкам, производительностью и простотой поддержки. Вот окончательная (и аннотированная) версия MyResourceWrapper, для которой используется этот "официальный" шаблон.
Обратите внимание на то, что теперь MyResourceWrapper определяет приватный вспомогательный метод, с именем Cleanup. Если для его аргумента указано true (истина), это значит, что сборку мусора инициировал пользователь объекта. И тогда мы должны освободить и управляемые, и неуправляемые ресурсы. Но если "уборка" инициирована сборщиком мусора, то при вызове CleanUp следует указать false (ложь), чтобы внутренние объекты не освобождались (поскольку мы не можем гарантировать, что они все еще находятся в памяти). Наконец, перед выходом из CleanUp член-переменная disposed логического типа устанавливается равной true, чтобы Dispose можно было вызывать многократно без появления сообщений об ошибках.
Исходный код. Проект FinalizableDisposableClass размещен в подкаталоге, соответствующем главе 5.
На этом наше обсуждение того, как среда CLR управляет объектами с помощью сборки мусора, завершается. Остались нерассмотренными еще ряд вопросов, связанных с процессом сборки мусора (это, например, слабые ссылки и восстановление объектов), но вы теперь имеете достаточно знаний для того, чтобы продолжить исследование данной темы самостоятельно в удобное для вас время.
Резюме
Целью этой главы было обсуждение процесса сборки мусора. Вы могли убедиться, что сборщик мусора начинает работу только тогда, когда становится невозможным выделить необходимый объем управляемой динамической памяти (или когда из памяти выгружается домен данного приложения). Вы можете быть уверены в том, что сборка мусора будет выполнена в оптимальном режиме с помощью соответствующего алгоритма Microsoft, использующего генерации объектов, вторичные потоки для финализации, объектов и области управляемой динамической памяти, предназначенные для размещения больших объектов.
В этой же главе объясняется, как с помощью типа класса System.GC взаимодействовать со сборщиком мусора. Это требуется при создании типов, предусматривающих финализацию или освобождение ресурсов. Типы, предусматривающие финализацию, представляют собой классы с переопределенным виртуальным методом System.Object.Finalize, который (в будущем) должен обеспечить освобождение неуправляемых ресурсов. Объекты, предуcматриваюцие освобождение ресурсов, являются классами (или структурами), в которых реализуется интерфейс IDisposable. В рамках этого подхода пользователю объекта предлагается открытый метод, который должен быть вызван пользователем для выполнения внутренней ''уборки" сразу же, как только это потребуется. Наконец, вы узнали об "официальном" формализованном шаблоне освобождения ресурсов, в котором комбинируются оба указанных подхода.