2010-06-15 4 views
5

(1) Я прочитал много вопросов о IDisposable, где ответы не рекомендуют использовать Finalize, если вам действительно не нужно из-за связанного с этим процесса времени.
Я не видел, насколько это стоит и как часто это оплачивается. Каждые миллисекунды? второй? час, день и т. д.Стоимость финализации в .Net

(2) Также мне кажется, что Finalize удобен, когда не всегда известно, может ли объект быть удален. Например, класс шрифта рамки. Элемент управления не может избавиться от него, потому что он не знает, является ли общий шрифт. Шрифт, как правило, создается во время разработки, поэтому пользователь не будет знать, чтобы его утилизировать, поэтому завершите работу, чтобы, наконец, избавиться от него, когда ссылок нет. Это правильное впечатление?

+4

Прочитано: http://msdn.microsoft.com/en-us/library/ms973837.aspx – 2010-06-15 14:20:00

+0

Что касается класса «Font», он фактически используется для двух совершенно разных целей в .net; он инкапсулирует набор информации о шрифте (семейство, размер, стиль и т. д.), а также инкапсулирует объект поиска GDI. Свойство 'Font' элемента управления интересует только прежняя информация; элементам управления будет все равно, если их свойство 'Font' установлено на шрифт, который является' Dispose'd (даже если 'Dispose' возникает до того, как свойство будет установлено!) Следовательно, если вы хотите иметь поле, которое будет использоваться для установки свойств 'Font' управления, можно было создать« Шрифт »для него, а затем ... – supercat

+0

... сразу же« Dispose ». Скорее всего, несколько странный образец, но в корне указывающий на тот факт, что .net должен был использовать класс или структуру 'FontInfo' для элемента управления' Font'. – supercat

ответ

7

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

+0

Лучшее объяснение, чем я мог бы дать. – Meiscooldude

4

Доработки концептуально отличается от Dispose. Finalize может только свободных неуправляемые ресурсы. Утилизировать можно бесплатно управляемым . и неуправляемые ресурсы Вы должны использовать каждый по мере необходимости (Обратите внимание, что класс с Finalizer всегда должны осуществлять IDisposable)

Dispose должен вызываться явно, Доработка можно назвать только GC

Update...: См. Мой блог на How to Implement IDisposable and Finalizers: 3 Easy Rules.

+0

Это не совсем правильно. Вы должны держать финализатор коротким, но если вам нужно сделать работу там, вы можете. (обратите внимание на процедуры отладки) – Spence

+1

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

+0

@Spence - ваш второй комментарий - почему ваш первый комментарий обычно невозможен. ;) Есть несколько исключений, таких как 'Console.WriteLine', но, как правило, то, что я называю« логикой выключения », возможно только в« Dispose », а не в Finalizer. –

0

Finalize чрезвычайно полезен в качестве двойной проверки. Если сбой или чей-то плохой код не удаляет ваш объект, прежде чем он выходит из сферы действия, убедитесь, что его ресурсы будут выпущены в финализаторе.

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

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

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

1

Я отвечу на ваш второй вопрос.

No, Finalize не должен использоваться таким образом. На самом деле, за исключением только очень небольшого числа случаев, вы должны переопределить Finalize (или объявить деструктор в C#), если класс напрямую содержит неуправляемые ресурсы.

Вопрос, который вы описали, является собственностью. Владелец класса IDisposable несет ответственность за его срок службы и решение о том, когда позвонить Dispose. Другие части кода могут свободно использовать этот класс, но поскольку они не могут требовать права собственности, они не должны участвовать в управлении жизненным циклом этого класса.

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