Разве обработчики событий останавливают сбор мусора?

Если у меня есть следующий код:

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

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

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

Ответ 1

По конкретному вопросу: "Будет ли pClass быть собранным мусором": подписка на события не влияет на коллекцию pClass (как издателя).

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

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

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

publisher.SomeEvent += target.SomeHandler;

тогда "издатель" сохранит "цель" в живых, но "цель" не сохранит "издателя".

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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