.NET: Любой способ сказать, когда объект утилизируется / сборщик мусора? - PullRequest
7 голосов
/ 30 марта 2010

Учитывая объект, есть ли способ получить уведомление о том, когда этот объект собирается мусором?

Я играю с тем, чтобы методы расширения C # вели себя как миксины (особенно при добавлении логирования). Таким образом, в основном каждый объект получает новый метод Logger (), который возвращает ILog, который создается и кэшируется в зависимости от объекта, являющегося целью метода расширения.

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

Кто-нибудь знает способ сделать это?

Ответы [ 3 ]

11 голосов
/ 30 марта 2010

Я думаю, что здесь обычно делается то, что вы поддерживаете список Слабые ссылки . С помощью слабой ссылки вы можете определить, был ли объект, на который вы ссылаетесь, сборщиком мусора или нет, проверив свойство IsAlive .

3 голосов
/ 25 августа 2012

В .net 4.0 существует тип ConditionalWeakTable, который может использоваться, хотя и несколько неловко, для запроса уведомления, когда произвольный объект становится подходящим для завершения. Если ConditionalWeakTable содержит запись, отображающую один объект (скажем, 451-й созданный объект) на другой объект (скажем, 730-й созданный объект), то пока запись остается в таблице, а корневые ссылки существуют как на таблицу, так и на объект # 451, таблица будет считаться корневой ссылкой на объект # 730. Если корневая ссылка на объект # 451 отсутствует, таблица перестанет быть корневой ссылкой на объект # 730.

Следовательно, если объект № 730 содержит ссылку на таблицу и объект № 730 существует вне таблицы, объект № 730 получит право на финализацию одновременно с объектом № 451. Если объект # 730 переопределяет Finalize(), это переопределение можно использовать как уведомление о том, что объект # 451 получил право на финализацию.

Обратите внимание, что финализатор для объекта # 730 сработает только один раз, даже если объект # 451 воскресит себя и перерегистрирует для завершения. Можно было бы написать код, который бы запускал уведомление примерно в то время, когда объект # 451 действительно становится мертвым и похороненным, даже если он сначала воскрешается несколько раз, но нет особо чистого способа сделать это.

1 голос
/ 30 марта 2010

Деструктор вызывается во время GC.

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