我正在开发一个有多种形式的C#应用程序
当我打开其中一个表单时,我添加了一个这样的事件监听器:SomeClass.MotionCompleted += new EventHandler(HandlerMethod);
。 MotionCompleted事件是静态事件。
我注意到在关闭此表单后,HandlerMethod仍会在事件发生时被调用,然后导致异常,因为它尝试更新表单上不再存在的内容。
即使表单不再存在,eventlistener如何存在并响应事件?一旦调用了form.Close()或this.Close(),就不应该自动取消挂钩事件列表器,以便不再调用它们吗?
答案 0 :(得分:6)
这是静态事件的罪恶! :)那里有managed leak。
覆盖表单的OnClosing并取消注册处理程序:
protected override void OnClosing(CancelEventArgs e) {
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
}
答案 1 :(得分:2)
Someclass.MotionCompleted -= new EventHandler(HandlerMethod);
本文展示了很多有关C#中事件的提示:http://www.yoda.arachsys.com/csharp/events.html
答案 2 :(得分:1)
要添加所有重复的答案,您也可以取消这种方式:
SomeClass.MotionCompleted -= HandlerMethod;
无论您使用-= HandlerMethod
还是-= new EventHandler(HandlerMethod)
,输出汇编代码都是相同的。
答案 3 :(得分:0)
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
只需将“+”更改为“ - ”
即可答案 4 :(得分:0)
你必须手动取消挂钩:
SomeClass.MotionCompleted -= HandlerMethod;
答案 5 :(得分:0)
您可以使用以下代码示例:
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
但是,您必须小心从包含注册它的HandlerMethod
对象的同一实例中取消事件。
答案 6 :(得分:0)
您需要手动取消挂钩事件,如下所示:
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
答案 7 :(得分:0)
不完全是。垃圾收集器不收集表单,因为事件处理程序仍然存在。静态事件处理程序不会被自己解开。您可以在表单onClosing方法中取消挂起任何指定的事件,如:
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
之后一切都应该有效。
答案 8 :(得分:0)
事件是强烈的参考:它们不能被垃圾收集,除非你明确地取消它们。
这就是为什么我建议你使用订阅和非替代方法来完成他们的工作并集中这个钩子(如果你不释放它们会导致内存泄漏)
private void subscribeAll()
{
SomeClass.MotionCompleted += new EventHandler(HandlerMethod);
// other subscription
}
private void unSubscribeAll()
{
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
// other subscription
}