如何在 C# 中取消事件处理程序
我正在开发一个具有多种表单的 C# 应用程序。
当我打开其中一个表单时,我添加一个事件侦听器,如下所示:SomeClass.MotionCompleted += new EventHandler(HandlerMethod); 。 MotionCompleted
事件是一个静态事件。
我注意到,关闭此表单后,当事件发生时,HandlerMethod
仍然会被调用,这会导致异常,因为它试图更新表单上不再存在的内容。
即使表单不再存在,事件侦听器如何存在并响应事件?一旦调用 form.Close()
或 this.Close()
,难道不应该自动取消事件侦听器的挂钩,以便它们不再被调用吗?
I am working on a C# application that has multiple forms.
When I open one of the forms I add an event listener like this: SomeClass.MotionCompleted += new EventHandler(HandlerMethod);
. The MotionCompleted
event is a static event.
I have noticed that after closing this form the HandlerMethod
still gets called when the event occurs which then causes an exception because it tries to update something on the form which doesn't exist anymore.
How can the event listener exist and respond to the event even though the form doesn't exist anymore? Once form.Close()
or this.Close()
is called shouldn't that automatically unhook the event listeners so that they do not get called anymore?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
这就是静态事件的邪恶之处! :) 你那里有一个托管泄漏。
覆盖表单的 OnClosing 并取消注册处理程序:
That's the evil of static events! :) You have a managed leak there.
Override the OnClosing of your form and deregister you handler:
本文展示了有关 C# 中的事件的许多技巧:
https://csharpin深度.com/articles/Events
This article shows a lot of tips regarding events in C#:
https://csharpindepth.com/articles/Events
要添加到所有重复的答案,您也可以通过这种方式取消挂钩:
无论您使用
-= HandlerMethod
还是-= new EventHandler(HandlerMethod)
,输出汇编代码都是相同的。To add to all the duplicate answers you can also unhook this way:
The output assembly code will be the same whether you use
-= HandlerMethod
or-= new EventHandler(HandlerMethod)
.只需将“+”更改为“-”
just change the "+" to "-"
您可以使用以下代码示例:
但是,您必须小心地从包含注册该事件的对象的
HandlerMethod
的同一对象实例中取消事件的挂钩。You can use this sample of code :
However, you must be careful to unhook your event from the same instance of the object containing
HandlerMethod
that the one which registered it.您需要像这样手动取消事件:
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
You need to manually unhook the event like this:
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
不完全是。该表单不会被垃圾收集器收集,因为事件处理程序仍然存在。静态事件处理程序不会自行解除挂钩。您可以在 onClosing 方法中取消任何分配的事件,例如:
之后一切都应该正常工作。
Not exactly. The form is not collected by the garbage collector because the event handler is still there. The static event handlers don't get unhooked by themselves. You can unhook any assigned event in the form onClosing method like:
After that everything should work.
事件是强引用:除非您明确取消引用它们,否则它们不能被垃圾收集。
这就是为什么我建议你编写一个订阅和取消订阅方法来完成它们的工作并集中这个钩子(如果你不释放它们,这将导致内存泄漏)
Events are strong reference : they cannot be garbage collected unless you explicitely dereferece them.
That's why I suggest youw rite a subscribe and an unsubscibe methods that will do their jobs and centralize this hooks (which will results in memory leaks if you don't free them)
您必须手动取消挂钩:
You have to unhook in manually: