winforms 如何在C#中取消挂钩事件处理程序

wgeznvg7  于 2022-11-16  发布在  C#
关注(0)|答案(9)|浏览(223)

我正在处理一个具有多个窗体的C#应用程序。
当我打开其中一个窗体时,我添加了一个事件侦听器,如下所示:SomeClass.MotionCompleted += new EventHandler(HandlerMethod);MotionCompleted事件是静态事件
我注意到,关闭此窗体后,当事件发生时,仍然会调用HandlerMethod,这会导致异常,因为它试图更新窗体上不再存在的内容。
即使表单不再存在,事件侦听器如何存在并响应事件?一旦调用form.Close()this.Close(),是否应该自动取消事件侦听器的挂钩,使它们不再被调用?

hmae6n7t

hmae6n7t1#

这就是静态事件的邪恶!:)你有一个managed leak在那里。
重写窗体的OnClosing并注销处理程序:

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

qlfbtfca2#

Someclass.MotionCompleted -= new EventHandler(HandlerMethod);

这篇文章展示了许多关于C#中事件的提示:
https://csharpindepth.com/articles/Events

3qpi33ja

3qpi33ja3#

要添加到所有重复的答案中,您也可以通过以下方式取消挂钩:

SomeClass.MotionCompleted -= HandlerMethod;

无论使用-= HandlerMethod还是-= new EventHandler(HandlerMethod),输出的汇编代码都是相同的。

jgovgodb

jgovgodb4#

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

只要把“+”改成“-”

gz5pxeao

gz5pxeao5#

您可以使用以下示例代码:

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

但是,您必须小心地将事件从包含HandlerMethod的对象的同一个示例(注册它的示例)中解除挂钩。

btxsgosb

btxsgosb6#

您需要像这样手动取消事件挂钩:SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

wlsrxk51

wlsrxk517#

不完全是。因为事件处理程序仍然存在,所以垃圾收集器不会收集表单。静态事件处理程序不会自己脱钩。您可以脱钩表单onClosing方法中的任何赋值事件,如下所示:

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

之后一切都应该工作。

y1aodyip

y1aodyip8#

事件被强烈引用:除非您显式取消引用它们,否则它们不能被垃圾收集。
这就是为什么我建议你写一个subscribe和一个unsubscribe方法,它们将完成它们的工作并集中这些钩子(如果你不释放它们,这将导致内存泄漏)

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

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

b09cbbtk9#

您必须手动脱钩:

SomeClass.MotionCompleted -= HandlerMethod;

相关问题