Финализатор и IDisposable - PullRequest
       48

Финализатор и IDisposable

9 голосов
/ 07 октября 2010

На основании документации (MSDN: ссылка ) ясно, что при реализации финализатора следует использовать шаблон IDisposable.

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

На мой взгляд, если класс имеет только управляемые ресурсы и если вы не вызываете Dispose, управляемые ресурсы автоматически очищаются с помощью GC и, следовательно, нет необходимости реализовывать финализатор. Я не прав?

Кроме того, что если я использую свой метод Dispose для очистки обработчиков событий. Как Dispose не будет автоматически вызываться GC, должен ли я реализовать Finalizer, чтобы гарантировать, что обработчики событий будут разорваны?

Ответы [ 6 ]

10 голосов
/ 07 октября 2010

Нет, вам не нужно реализовывать финализатор, если у вас есть класс, который реализует IDisposable (то есть, если вы правильно реализовали шаблон и у вас есть только управляемые ресурсы, которыми можно распоряжаться).

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

10 голосов
/ 07 октября 2010

Не следует добавлять финализатор, если у вас нет неуправляемых ресурсов.

Класс, которому принадлежат управляемые одноразовые ресурсы, но не неуправляемые ресурсы, должен реализовывать полный шаблон Dispose, но не иметь финализатор.

Если класс не sealed, он должен вызвать GC.SuppressFinalize(this) в своем методе Dispose(), если унаследованный класс добавляет финализатор.

2 голосов
/ 07 октября 2010
  1. Нет, вы правы, если ваш объект содержит объект, который содержит неуправляемый ресурс, вы должны реализовать IDisposable, чтобы вы могли вызывать его Dispose на вашем Dispose, но вам не нужен финализаторпоскольку его финализатор будет иметь дело с этим вопросом.

  2. Действительно, попытка что-либо сделать с финализируемым участником из финализатора чревата, так как порядок выполнения финализаторов не является детерминированным, поэтомувы можете получить некоторые неприятные ошибки, если попытаетесь это сделать.

  3. Как правило, гораздо лучше иметь класс, содержащий 1 или 0 неуправляемых ресурсов.И если у него есть 1 неуправляемый ресурс, у него должно быть как можно меньше другого состояния, необходимого для работы с ним (т.е. никаких других одноразовых членов).SafeHandle - хороший способ справиться с этим.Если классу необходимо иметь дело с несколькими неуправляемыми ресурсами, он должен делать это, обрабатывая указанные ресурсы с помощью этих классов-обработчиков.Тогда финализатор и IDisposable становится легким;либо у вас есть единственный неуправляемый ресурс для работы с обоими (подавьте финализатор, если вызывается утилизация), либо вам нужен только IDisposable.

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

0 голосов
/ 07 октября 2010

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

0 голосов
/ 07 октября 2010

Да, если у вас есть только управляемые ресурсы, они будут очищены GC, когда происходит сборка мусора (и нет никаких живых ссылок, указывающих на них)

Но в этом случае зачем вам нужно реализовывать IDisposable для вашего типа? Я имею в виду, вы, кажется, считаете, что в вашем случае не избавление от вашего объекта не является большой проблемой, тогда почему кто-то распоряжается ими?

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

Во время первой сборки мусора, во время которой объект должен быть очищен, он не сможет выполнить финализатор. Объект будет считаться GC долгоживущим, даже если он уже должен быть очищен.

0 голосов
/ 07 октября 2010

Если у вас есть только управляемые ресурсы, вам вообще не нужно внедрять IDisposable.IDisposable предназначен для очистки вещей за пределами домена GC, таких как собственные дескрипторы, соединения с базой данных и т. Д.

Если ваш элемент управления содержит элементы управления, реализующие IDisposable, и они должны высвобождать собственные ресурсы, то вам все равно нужно реализоватьIDisposable шаблон и дать вашему ребенку контроля возможность распоряжаться.

Причиной вызова Dispose () в финализаторе является последнее средство: если объект не был правильно утилизирован, GC сделает это как последнее усилие по канаве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...