Что происходит, когда событие запускается и пытается выполнить обработчик события в объекте, который больше не существует? - PullRequest
5 голосов
/ 29 мая 2009

В одном классе, ClassA, у меня есть объект таймера. В этом классе я регистрирую обработчики событий для события истекшего таймера. В другом классе, ClassB, у меня есть публичный обработчик события истекшего таймера. Поэтому я регистрирую обработчик событий из ClassB в ClassA следующим образом:

myTimer.Elapsed += ClassBInstance.TimerElapsed

Что произойдет, если я создам новый экземпляр ClassBInstance, и событие прошедшего с таймера срабатывает, когда предыдущий экземпляр обработчика событий ClassB все еще привязан к событию Elapsed таймера?

Например:

ClassB classBInstance = new ClassB();
myTimer.Elapsed += classBInstance.TimerElapsed

classBInstance = new ClassB();
myTimer.Elapsed += classBInstance.TimerElapsed

Ответы [ 4 ]

11 голосов
/ 29 мая 2009

AFAIK, ClassBInstance не является сборщиком мусора, если есть зарегистрированные события, потому что событие содержит ссылку на него.

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

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

4 голосов
/ 29 мая 2009

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

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

3 голосов
/ 29 мая 2009

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

0 голосов
/ 05 июня 2009

Вы можете использовать мой WeakEventHandler, основываясь на WeakReference. Поскольку он сохраняет слабую ссылку на прослушиватель событий, он не заставляет слушателя жить.

см. Этот ответ

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