我需要移除这种事件处理程序吗?

22 浏览
0 Comments

我需要移除这种事件处理程序吗?

如果我创建了一个.NET类,它使用匿名函数订阅事件,就像这样:

void MyMethod()
{
   Application.Current.Deactivated += (s,e) => { ChangeAppearance(); };
}

这个事件处理程序会成为根,阻止我的类被垃圾回收吗?

如果不是,那太好了!但是如果是,你能给我展示一下删除语法吗?只是使用相同的代码进行-=似乎不对。

admin 更改状态以发布 2023年5月23日
0
0 Comments

我认为你需要取消订阅,因为事件提供者(应用程序)的生命周期 - 或者至少可以 - 比您的消费者更长。因此,每个订阅实例在应用程序仍然存在时死亡将创建内存泄漏。

您正在向事件订阅匿名委托。这就是您无法以相同方式取消订阅的原因,因为您无法再次寻址它。实际上,您在订阅时创建该方法,而且您没有存储对新创建方法的指针。

如果您稍微更改实现以使用“真实”方法,则可以轻松地以相同的方式从事件中取消订阅它:

Application.Current.Deactivated += ChangeAppearance;
Application.Current.Deactivated -= ChangeAppearance;
private void ChangeAppearance(object sender, EventArgs eventArgs)
{
    throw new NotImplementedException();
}

0
0 Comments

你可以像Simon D.建议的那样使用一个“真正的”方法,或者这样做:

EventHandler handler = null;
handler = (s,e) => { 
    Application.Current.Deactivated -= handler;
    ChangeAppearance();
};
Application.Current.Deactivated += handler;

由于这种方法有点丑陋,违背了使用Lambda的简洁目的,我可能会将其重构为一个方法。但知道还有其他方法也是有用的。

警告:不用说,你必须非常小心,不要在订阅事件和实际调用事件之间任何时候都改变handler的值,否则取消订阅的部分就无法正常工作。

0