2010-11-05 2 views
2

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

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

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

ответ

6

Это зло статических событий! :) У вас есть managed leak.

Override OnClosing вашей формы и дерегистрировать вам обработчик:

protected override void OnClosing(CancelEventArgs e) { 
    SomeClass.MotionCompleted -= new EventHandler(HandlerMethod); 
} 
+0

Я подумал, что это был ответ, я просто надеялся, что это будет способ сделать это автоматически! – PICyourBrain

+0

Вы должны сделать некоторые чтения в сборщике мусора .net. Поскольку событие является статическим, оно является «корневым» объектом a, содержит обработчик со ссылкой на вашу форму. Из-за этой ссылки ваша форма остается в живых, даже если вы думаете, что это не так. – Stormenet

+3

OnFormClosing не является технически корректным, его можно отменить. Использовать OnFormClosed. Вырезание и вставка метода Dispose() из файла конструктора является еще более правильным. Это так же автоматически, как и в случае с ним. –

0
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod); 

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

0

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

SomeClass.MotionCompleted -= HandlerMethod; 
0

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

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod); 

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

0

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

0

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

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod); 

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

0

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

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

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

private void unSubscribeAll() 
{ 
    SomeClass.MotionCompleted -= new EventHandler(HandlerMethod); 
    // other subscription 
} 
1

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

SomeClass.MotionCompleted -= HandlerMethod; 

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

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