2

我正在开发具有多种形式的 C# 应用程序。
当我打开其中一个表单时,我会添加一个事件侦听器,如下所示:SomeClass.MotionCompleted += new EventHandler(HandlerMethod);. MotionCompleted 事件是一个静态事件

我注意到,在关闭此表单后,当事件发生时仍会调用 HandlerMethod,这会导致异常,因为它会尝试更新表单上不再存在的内容。

即使表单不再存在,事件监听器如何存在并响应事件?一旦 form.Close() 或 this.Close() 被调用,不应该自动解除事件监听器的钩子,以便它们不再被调用吗?

4

9 回答 9

6

这就是静态事件的弊端!:) 你那里有一个受控的泄漏

覆盖表单的 OnClosing 并注销您的处理程序:

protected override void OnClosing(CancelEventArgs e) {
    SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
}
于 2010-11-05T13:58:37.040 回答
2
Someclass.MotionCompleted -= new EventHandler(HandlerMethod);

这篇文章展示了很多关于 C# 事件的提示:http ://www.yoda.arachsys.com/csharp/events.html

于 2010-11-05T13:58:00.770 回答
1

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

SomeClass.MotionCompleted -= HandlerMethod;

无论您使用-= HandlerMethod还是,输出的汇编代码都是一样的-= new EventHandler(HandlerMethod)

于 2010-11-05T15:02:36.573 回答
0
SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

只需将“+”更改为“-”

于 2010-11-05T13:58:43.297 回答
0

您必须手动取消挂钩:

SomeClass.MotionCompleted -= HandlerMethod;
于 2010-11-05T13:59:01.757 回答
0

您可以使用此代码示例:

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

但是,您必须小心将您的事件从包含HandlerMethod注册它的对象的同一实例中解开。

于 2010-11-05T13:59:15.577 回答
0

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

于 2010-11-05T13:59:23.153 回答
0

不完全是。垃圾收集器不会收集表单,因为事件处理程序仍然存在。静态事件处理程序不会自行解开。您可以以 onClosing 方法的形式取消挂钩任何分配的事件,例如:

SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);

之后,一切都应该工作。

于 2010-11-05T13:59:58.257 回答
0

事件是强引用:除非您明确取消引用它们,否则它们不能被垃圾收集。

这就是为什么我建议你编写一个 subscribe 和一个 unsubscibe 方法来完成他们的工作并集中这个钩子(如果你不释放它们会导致内存泄漏)

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

private void unSubscribeAll()
{
  SomeClass.MotionCompleted -= new EventHandler(HandlerMethod);
  // other subscription
}
于 2010-11-05T14:02:25.663 回答