Остановили ли обработчики событий сборку мусора? - PullRequest
173 голосов
/ 18 ноября 2008

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

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

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

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

Ответы [ 4 ]

192 голосов
/ 18 ноября 2008

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

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

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

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

publisher.SomeEvent += target.SomeHandler;

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

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

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

7 голосов
/ 18 ноября 2008

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

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

7 голосов
/ 18 ноября 2008

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

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

0 голосов
/ 07 июня 2012

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

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