你需要在析构函数删除事件处理程序? [英] Do you need to remove an event handler in the destructor?

查看:284
本文介绍了你需要在析构函数删除事件处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用一些用户控件这获得创建和运行时我的应用程序内被摧毁(通过创建和使用这些控件关闭子窗口内)。结果
这是一个WPF用户控件,并从 System.Windows.Controls.UserControl 继承。没有的Dispose()方法我可以覆盖。结果
PPMM 辛格尔顿用的生存期我的应用程序。结果
现在在我的(WPF)的构造用户控件,我添加事件处理程序:

I use some UserControls which get created and destroyed within my application during runtime (by creating and closing subwindows with these controls inside).
It's a WPF UserControl and inherits from System.Windows.Controls.UserControl. There is no Dispose() method I could override.
PPMM is a Singleton with the same lifetime as my application.
Now in the constructor of my (WPF) UserControl, I add an event handler:

public MyControl()
{
    InitializeComponent();

    // hook up to an event
    PPMM.FactorChanged += new ppmmEventHandler(PPMM_FactorChanged);
}



我习惯了在析构函数删除这样的事件处理程序:

I got used to removing such event handler in the destructor:

~MyControl()
{
    // hook off of the event
    PPMM.FactorChanged -= new ppmmEventHandler(PPMM_FactorChanged);
}



今天,我偶然发现了这一点,并想知道:

Today I stumbled upon this and wondered:

1)这是neccessary?抑或是GC照顾它?

2)这是否甚至工作?或者,我会存储新创建 ppmmEventHandler

2) Does this even work? Or would I have to store the newly created ppmmEventHandler?

我期待着您答案

推荐答案

由于 PPMM 是一个长期存在的对象(单身),那么这段代码并没有太大的意义。

Since PPMM is a long-lived object (singleton), then this code doesn't make much sense.

这里的问题是,只要该事件处理程序引用对象,的它不会符合垃圾收集的,因为至少只要拥有该事件的其他对象是活的。

The problem here is that as long as that event handler is referencing the object, it will not be eligible for garbage collection, as least as long as that other object that owns the event is alive.

由于在析构函数等,把任何事情都是没有意义的,为两种:

As such, putting anything in the destructor is pointless, as either:


  1. 事件处理程序已被移除,从而使物体变得符合垃圾收集

  2. 事件处理程序不除,所属对象不符合垃圾收集,从而终结将永远不会被调用

  3. 这两个对象是符合垃圾收集,在这种情况下,你不应该在所有访问其他对象的终结,因为你不知道它的内部状态

在短,唐'T这样做

现在,一个不同的观点可以说关于添加这样的代码到的Dispose 方法,当你实施的IDisposable 。在的情况下,它完全有道理的,因为它的用户代码正在调用的Dispose ,在预定和控制点。

Now, a different argument could be said about adding such code to the Dispose method, when you're implementing IDisposable. In that case it fully makes sense since its usercode that is calling Dispose, at a predefined and controlled point.

终结(析构函数),然而,这只是调用的时候,对象符合垃圾收集和有一个终结,在这种情况下,有没有意义的。

The finalizer (destructor), however, is only called when the object is eligible for garbage collection and has a finalizer, in which case there is no point.

至于问题NBR。 2,我拿的,那么,你可以在我可以从这样的事件退订。你需要坚持到您用于订阅委托的唯一情况是,当你周围构建一个匿名方法或lambda表达式的委托。当你构建它周围现有的方法,将工作

As for question nbr. 2, which I take as "Can I unsubscribe from events like that", then yes, you can. The only time you need to hold on to the delegate you used to subscribe with is when you're constructing the delegate around an anonymous method or a lambda expression. When you're constructing it around an existing method, it will work.

修改: WPF。没错,没有看到标记。对不起,我的回答其余没有太大的意义WPF和因为我没有WPF的大师,我真的不能说。然而,有解决这个问题的方法。这是完全合法的,这里SO挖走另一个答案的内容,如果你能改善它。所以,如果有人知道如何正确使用WPF用户控件做到这一点,你可以自由地抬起我的回答的整个第一部分并添加WPF中的相关内容。

Edit: WPF. right, didn't see that tag. Sorry, the rest of my answer doesn't make much sense for WPF and since I am no WPF-guru, I can't really say. However, there's a way to fix this. It's entirely legal here on SO to poach the content of another answer if you can improve it. So if anyone knows how to properly do this with a WPF usercontrol, you're free to lift the entire first section of my answer and add the relevant bits of WPF.

<击>
修改:让我在里面的评论在这里也回答这个问题。

Edit: Let me respond to the question in the comment inside here as well.

由于有关类是用户控制,其寿命将被捆绑到一个表单。当表单被关闭,它会处理所有的子控件,它拥有,换言之,的已经有在座​​

Since the class in question is a user-control, its lifetime will be tied to a form. When the form is closing, it will dispose of all child controls that it owns, in other words, there is already a Dispose method present here.

正确的方法为用户控件来处理这个问题,如果它管理自己的活动,是为了解开事件处理程序中的Dispose方法。

The correct way for a user control to handle this, if it manages its own events, is to unhook the event handlers in the Dispose method.

(休息删除)

这篇关于你需要在析构函数删除事件处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆