2010-08-11 3 views
16

Являются ли финализаторы гарантированно выполненными в .NET в какой-то момент (резервные перебои с подачей электроэнергии и т. П.)? Я знаю, как работает GC и что он недетерминирован, когда именно они будут работать.Всегда ли исполняются финализаторы .net?

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

ответ

24

Финализаторы может быть на самом деле никогда выполняется, так как Raymond Chen explains. Вид смешно, что этот вопрос задают во время его ежегодной недели CLR, всего два дня после того, как он объяснил :)

Для ленивых, то (или, вернее, один) вывод:

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

Если вам интересно, можете ли вы положиться на финализаторы, это уже все, что вам нужно знать: не полагайтесь на финализаторы.

Как Raymond Chen также говорится в связанной статье:

Финализаторы подстраховка, а не основным средством для освоения ресурсов.

Если вы ищете, как освободить ресурсы, взгляните на одноразовый шаблон.


Финализатор не может работать, например, если:

  • Другой финализатор генерирует исключение.
  • Еще один финализатор занимает более 2 секунд.
  • Все финализаторы вместе занимают более 40 секунд.
  • AppDomain разрушился или выгружен (хотя вы можете обойти это с критической финализации (CriticalFinalizerObject, SafeHandle или что-то в этом роде)
  • Нет мусора не происходит
  • Процесс врезается

(Примечание: Значения времени могут меняться со временем, but were certainly true some time ago.)

Я думаю, что есть много вещей, которые могут привести к тому, что финализаторы никогда не будут работать. Нижняя строка, кроме цитаты от г-на Чена, что финализаторы являются безопасность при уменьшают влияние ошибок, потому что, например, ресурсы освобождаются когда-то, что лучше никогда, если вы забудете это сделать.

+0

Не могли бы вы процитировать больше важных частей? И да, возможно, аскер с нетерпением ждал именно этой связи. ;) – mafu

+0

На самом деле, поскольку многие люди спрашивают, как они могут полагаться на поведение финализатора, я думаю, что я * процитировал одну наиболее важную часть;) С другой стороны, другие поля в статье могут быть интересными. – OregonGhost

+0

@OregonGhost: Я понимаю это право: если 20 финализаторов каждый забирают 1,95 секунды каждый, это hunky dory, и все будет выполнено - займет 39 секунд. Если требуется 2.05 секунды, выполнение всех остальных пропущено. Это кажется довольно сломанным. Было бы довольно грубо прерывать финализатор, который занимает более 2 секунд, чтобы позволить другим запускать на оставшуюся часть 40-секундного тайм-аута. Но сплетение вещей через две секунды показалось бы неудачным. – supercat

6

Если финализатор выбрасывает исключение, другие финализаторы не будут выполняться.

Вы также можете подавить финализаторы, если вы звоните SuppressFinalizer на объекте.

От MSDN (Object.Finalize):

Метод Доработки может не выполняться до завершения или не может работать вообще в следующих исключительных случаях:

  • Другого финализатор блоки неопределенно долго (идет в бесконечный цикл, пытается получить блокировку, которую он никогда не сможет получить и т. д.). Поскольку среда выполнения пытается запустить финализаторы до завершения, другие финализаторы могут не вызываться, если финализатор блокирует бесконечно.
  • Процесс завершается, не давая исполняющую систему шанс очистить. В этом случае первое уведомление о завершении процесса является уведомлением DLL_PROCESS_DETACH.
+0

Не могли бы вы добавить источник для «исключения»? – mafu

+0

Обратите внимание, что «переходит в бесконечный цикл», в реализации CLR означает «занимает более двух секунд», как описано здесь: http://nitoprograms.blogspot.com/2009/08/finalizers-at-process- exit.html – OregonGhost

+0

@mafutrct - См. здесь: http://stackoverflow.com/questions/1538630/exceptions-during-finalize-what-methodology-are-you-using-to-detect-garbage-co – Oded