Как отцепить обработчики событий в C # - PullRequest
2 голосов
/ 05 ноября 2010

Я работаю над приложением C #, которое имеет несколько форм.
Когда я открываю одну из форм, я добавляю прослушиватель событий, например так: SomeClass.MotionCompleted += new EventHandler(HandlerMethod);.Событие MotionCompleted представляет собой статическое событие .

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

Как может существовать Eventlistener и отвечать на событие, даже если форма больше не существует?После вызова form.Close () или this.Close () разве это не должно автоматически отсоединять списки событий, чтобы они больше не вызывались?

Ответы [ 9 ]

6 голосов
/ 05 ноября 2010

Это зло статических событий! :) У вас есть управляемая утечка .

Переопределите OnClosing вашей формы и отмените регистрацию вашего обработчика:

protected override void OnClosing(CancelEventArgs e) {
    SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
}
2 голосов
/ 05 ноября 2010
Someclass.MotionCompleted -= new EventHandler(HandlerMethod);

В этой статье приведено множество советов относительно событий в C #: http://www.yoda.arachsys.com/csharp/events.html

1 голос
/ 05 ноября 2010

Чтобы добавить ко всем дублирующимся ответам, вы также можете отцепить этот путь:

SomeClass.MotionCompleted -= HandlerMethod;

Выходной код сборки будет одинаковым независимо от того, используете ли вы -= HandlerMethod или -= new EventHandler(HandlerMethod).

0 голосов
/ 05 ноября 2010

События являются надежной ссылкой: они не могут быть собраны сборщиком мусора, если вы явно не разыменуете их.

Именно поэтому я предлагаю вам использовать методы подписки и рассылки, которые будут выполнять свою работу и централизовать эти хуки (что приведетутечки памяти, если вы их не освободите)

private void subscribeAll()
{
  SomeClass.MotionCompleted += new EventHandler(HandlerMethod);
  // other subscription
}

private void unSubscribeAll()
{
  SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
  // other subscription
}
0 голосов
/ 05 ноября 2010

Не совсем.Форма не собрана сборщиком мусора, потому что обработчик событий все еще там.Обработчики статических событий сами по себе не отцепляются.Вы можете отцепить любое назначенное событие в форме метода onClosing, например:

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

После этого все должно работать.

0 голосов
/ 05 ноября 2010

Вам необходимо вручную отцепить событие следующим образом: SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

0 голосов
/ 05 ноября 2010

Вы можете использовать этот образец кода:

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

Однако вы должны быть осторожны, чтобы отцепить событие от того же экземпляра объекта, содержащего HandlerMethod, что и тот, который его зарегистрировал.

0 голосов
/ 05 ноября 2010

Вы должны отцепить вручную:

SomeClass.MotionCompleted -= HandlerMethod;
0 голосов
/ 05 ноября 2010
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

просто измените "+" на "-"

...