Стоимость завершает в .NET

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

(2) Кроме того, мне кажется, что Завершают, удобно, когда не всегда известный, если объект может быть расположен. Например, класс шрифта платформы. Управление не может избавиться от него, потому что это не знает, совместно используется ли шрифт. Шрифт обычно создается во время проектирования, таким образом, пользователь не будет знать для расположения, он, поэтому для завершения умирает для окончательного избавлений от него, когда нет никаких оставленных ссылок. Это - корректное впечатление?

5
задан Jules 15 June 2010 в 13:55
поделиться

5 ответов

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

7
ответ дан 18 December 2019 в 14:42
поделиться
1
ответ дан 18 December 2019 в 14:42
поделиться

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

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

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

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

0
ответ дан 18 December 2019 в 14:42
поделиться

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

Dispose должен вызываться явно; Finalize может быть вызван только сборщиком мусора.

Обновление: см. Мое сообщение в блоге на Как реализовать IDisposable и Finalizers: 3 простых правила .

4
ответ дан 18 December 2019 в 14:42
поделиться

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

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

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

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

1
ответ дан 18 December 2019 в 14:42
поделиться