Финализаторы, как гарантируют, будут выполнены в.NET в какой-то момент (запасные перебои в питании и т.п.)? Я знаю, как GC работает и что это недетерминировано, когда точно они будут работать.
(Поиск не отобразил хорошие ответы, таким образом, я добавляю этот вопрос в больших ожиданиях слияния с not-so-easy-to-discover фактическими ответами. Кроме этого, я уже знаю ответ, и собираюсь добавить его после нескольких дней в случае, если никто не упомянул это.)
Финализаторы могут на самом деле никогда не выполняться, как Раймонд Чен объясняет . Довольно забавно, что этот вопрос задают во время его ежегодной недели CLR, всего через два дня после того, как он его объяснил :)
Для ленивых вывод (или, скорее, один):
Правильно написанная программа не может Предположим, что финализаторы когда-либо запустятся.
Если вам интересно, можно ли полагаться на финализаторы, это уже все, что вам нужно знать: не полагайтесь на финализаторы.
Как утверждает Раймонд Чен в связанной статье:
Финализаторы - это подстраховка, а не основное средство для освоения ресурсов.
Если вы ищете, как освободить ресурсы, обратите внимание на шаблон Disposable.
Финализатор может не работать, например, если:
(Примечание: значения времени может измениться с течением времени, , но определенно было верно некоторое время назад .)
Я думаю, есть еще много вещей, из-за которых финализаторы никогда не запускаются. Суть в том, что кроме цитаты из Г-н Чен, финализаторы - это подстраховка, которая снижает влияние ошибок , потому что, например, ресурсы высвобождаются когда-то , что лучше, чем никогда , если вы забываете сделать это явно.
Если финализатор выбрасывает исключение, другие финализаторы не выполняются.
Вы также можете подавить финализаторы, если вызовете SuppressFinalizer
на объекте.
Из MSDN (Object.Finalize):
Метод Finalize может не выполниться до конца или не выполниться вообще в следующих исключительных обстоятельствах:
- Другой финализатор блокируется на неопределенное время (переходит в бесконечный цикл, пытается получить блокировку, которую никогда не сможет получить, и так далее). Поскольку время выполнения пытается выполнить финализаторы до конца, другие финализаторы могут быть не вызваны, если финализатор блокируется на неопределенное время.
- Процесс завершается, не дав времени на очистку. В этом случае первым уведомлением среды выполнения о завершении процесса является уведомление DLL_PROCESS_DETACH.