2015-08-29 1 views
5

В книге Headfirst C# я получаю точку зрения, что «нецелесообразно сериализовать объект в своем финализаторе, поскольку для сериализации требуется, чтобы все дерево объектов находилось в куче, но вы можете в конечном итоге потерять жизненно важное значение часть вашей программы, потому что некоторые объекты могли быть собраны до запуска финализатора ».Почему не рекомендуется сериализовать объект в своем финализаторе?

Мой вопрос в том, что, поскольку мой объект получает ссылку на других (это означает, что есть хотя бы одна ссылка на другие объекты), как они могут быть собраны в мусор, прежде чем мой финализатор будет работать?

+1

Я не уверен в вашем вопросе, но имейте в виду, что нет гарантии, что ваш финализатор будет работать в первую очередь. –

+0

[Связанный вопрос здесь] (http://stackoverflow.com/q/2688636/314291) – StuartLC

+0

_Serializing_ объект, когда он по существу находится в процессе _snuffed-out_, возможно, является _bad design_. То, что это во власти _unknowns_, одинаково начинается – MickyD

ответ

8

Проблема с финализаторами том, что они обеспечивают очень мало гарантий:

  • они не гарантированно никогда не запускать
  • вы не можете предсказать, когда они будут работать
  • когда возможно, некоторые объекты, которые они ссылаются, уже завершены, поэтому ваш объект может находиться не в правильном состоянии.

Эрик Липперт имеет две большие сообщения в блоге об этом:

В любом случае, 99% из классов, которые вы когда-нибудь написать, вероятно, не имеют финализации на все. Очень мало случаев, когда они действительно необходимы. Если вам нужно выполнить очистку после того, как вы закончите с использованием объекта, вместо этого используйте IDisposable, по крайней мере, вы можете управлять детерминированным способом.

9

Потому что сборщик мусора не определяет порядок запуска финализаторов и не заботится о том, завершены ли ваши объекты из строя.

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

Это одно из ограничений того, что вы можете сделать в финализаторе: вы должны предположить, что все ваши дочерние объекты могли быть уничтожены уже. Документация Object.Finalize называет это в явном виде:

В финализаторах двух объектов не гарантирует выполнение в любом определенном порядке, даже если один объект относится к другим. То есть, если объект A имеет ссылку на объект B, и оба имеют финализаторы, объект B может быть уже завершен, когда начинается финализатор объекта A.

Смежные вопросы