2008-11-18 2 views
155

Если у меня есть следующий код:Разве обработчики событий останавливают сбор мусора?

MyClass pClass = new MyClass(); 
pClass.MyEvent += MyFunction; 
pClass = null; 

Будет Pclass сборщика мусора? Или он будет болтаться, все еще стреляя своими событиями всякий раз, когда они происходят? Должен ли я сделать следующее, чтобы разрешить сбор мусора?

MyClass pClass = new MyClass(); 
pClass.MyEvent += MyFunction; 
pClass.MyEvent -= MyFunction; 
pClass = null; 
+9

Я собираюсь в предварительном порядке предложить читателям, интересующимся этим вопросом, что, возможно, стоит ознакомиться с легкими событиями/слабыми шаблонами событий, которые НЕ предотвращают сбор мусора. Хороший SO-бутстрап в эту тему http://stackoverflow.com/questions/185931/weakreference-and-event-handling – fostandy 2010-05-13 06:36:49

+13

Примечание для потомков: установка ссылки на null просто задерживает сборщик мусора, расширяя на одну строку объем ссылка. .NET не VB6. – 2011-12-13 03:51:12

ответ

172

Для конкретного вопроса «Будет ли Pclass быть мусора»: подписка на события не оказывает никакого влияния на сбор Pclass (как издателя).

Для GC в целом (в частности, цель): зависит от того, является ли MyFunction статическим или основанным на экземпляре.

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

Обратите внимание: это односторонний; то есть, если мы имеем:

publisher.SomeEvent += target.SomeHandler; 

затем «издатель» будет держать «цель» живой, но «цель» не будет держать «издатель» жив.

Так что нет: если pClass собирается собираться в любом случае, нет необходимости отписывать слушателей. Однако, если pClass долговечен (дольше, чем экземпляр с MyFunction), то pClass может сохранить этот экземпляр живым, так что будет, чтобы отказаться от подписки, если вы хотите, чтобы цель была собрана.

Статические события, однако по этой причине очень опасны при использовании с обработчиками на основе экземпляров.

5

Да, pClass будет собираться мусором. Подписка на мероприятие не подразумевает, что какая-либо ссылка существует для pClass.

Нет, вам не нужно будет отсоединять обработчик, чтобы pClass был собран в мусор.

6

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

Если вы не уверены, что что-то получите, задайте себе следующий вопрос: есть ли еще ссылка на него? Обработчики событий ссылаются на экземпляр объекта, а не наоборот.

0

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

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