ВниМание
Разработчики.с.опытом.программирования.на.C++.заметят,.что.специальный.син-
таксис,.используемый.в.C#.для.определения.метода.финализации,.напоминает.
синтаксис.деструктора.C++ .Действительно,.в.предыдущих.версиях.спецификации.
С#.этот.метод.назывался.деструктором.(destructor) .Однако.метод.финализации.
работает.совсем.не.так,.как.неуправляемый.деструктор.C++,.что.сбивает.с.толку.
многих.разработчиков,.переходящих.с.одного.языка.на.другой
Беда.в.том,.что.разработчики.ошибочно.полагают,.что.использование.синтаксиса.
деструктора.означает.в.C#.детерминированное.уничтожение.объектов.типа,.как.
это.происходит.в.C++ .Но.CLR.не.поддерживает.детерминированное.уничтожение,.
поэтому.C#.не.может.предоставить.этот.механизм
Методы
Finalize
вызываются при завершении уборки мусора для объектов,
которые уборщик мусора определил для уничтожения. Это означает, что память
таких объектов не может быть освобождена немедленно, потому что метод
Finalize
может выполнить код с обращением к полю. Так как финализируемый объект
должен пережить уборку мусора, он переводится в другое поколение, вследствие
чего такой объект живет намного дольше, чем следует. Ситуация не идеальна в от-
ношении использования памяти, поэтому финализации следует по возможности
избегать. Проблема усугубляется тем, что при преобразовании поколения фина-
лизируемых объектов все объекты, на которые они ссылаются в своих полях, тоже
преобразуются, потому что они должны продолжать свое существование. Итак,
старайтесь по возможности обойтись без создания финализируемых объектов
с полями ссылочного типа.
Также следует учитывать, что разработчик не знает, в какой именно момент
будет выполнен метод
Finalize
, и не может управлять его выполнением. Методы
Finalize
выполняются при выполнении уборки мусора, которая может произойти
тогда, когда ваше приложение запросит дополнительную память. Кроме того, CLR
не дает никаких гарантий относительно порядка вызова методов
Finalize
. Итак,
следует избегать написания методов
Finalize
, обращающихся к другим объектам,
типы которых определяют метод
Finalize
; может оказаться, что последние уже
прошли финализацию. Тем не менее ничто не мешает вам обращаться к экзем-
плярам значимых типов или объектам ссылочных типов, не определяющих метод
Finalize
. Также будьте внимательны при вызове статических методов, потому что
эти методы могут обращаться к объектам, уже прошедшим финализацию; поведение
статического метода становится непредсказуемым.
Для вызова методов
Finalize
CLR использует специальный высокоприоритет-
ный поток. Таким образом предотвращаются ситуации взаимной блокировки, воз-
578
Do'stlaringiz bilan baham: |