如何在类的Dispose方法中取消订阅匿名函数?

5

我有一个A类...在它的构造函数中...我正在将一个匿名函数分配给Object_B的事件处理程序。

我如何从A类的Dispose方法中删除(取消订阅)它?

任何帮助都将不胜感激!谢谢

Public Class A
{

public A()
 {

 B_Object.DataLoaded += (sender, e) =>
                {
                   Line 1
                   Line 2
                   Line 3
                   Line 4
                };
 }

Public override void Dispose()
{
  // How do I unsubscribe the above subscribed anonymous function ?
}
}

B_Object是什么?它是A类的成员变量吗?它是否在A类之外的任何地方被访问;它可能有其他监听器吗? - Dax Fohl
是的,它是成员...属于类B的哪个实例 - Relativity
3个回答

8
基本上你不能这样做。要么将其移动到一个方法中,要么使用成员变量来保存委托以供稍后使用:
public class A : IDisposable
{
    private readonly EventHandler handler;

    public A()
    {
        handler = (sender, e) =>
        {
           Line 1
           Line 2
           Line 3
           Line 4
        };

        B_Object.DataLoaded += handler;
     }

     public override void Dispose()
     {
        B_Object.DataLoaded -= handler;
     }
}

所以,如果我们没有取消订阅它...那肯定会导致内存泄漏,对吧? - Relativity
1
@Relativity:不一定。你并没有真正谈论 B_Object.DataLoaded - 如果它实际上是一个实例事件而不是静态事件,那么如果对象被收集,事件订阅就不再重要了。这完全取决于上下文... - Jon Skeet
B_Object.DataLoaded 是一个实例事件,而非静态事件。请问你能否澄清一下:“如果对象被回收,事件订阅就没用了”? - Relativity
2
@Relativity:如果对象X订阅了对象Y的任何事件但没有取消订阅,则悬空的事件将导致对象X至少与对象Y一样长地停留在内存中。如果对象Y的内存生命周期比对象X的有用生命周期长得多,这可能是一个坏事。如果在对象Y的内存生命周期期间,将创建和丢弃许多对象X的实例,如果不灾难性的话,这可能非常糟糕。然而,如果当时间X变得无用时,Y将有资格进行收集,则悬空的订阅将不会使X保持活动状态。 - supercat
1
@Relativity:尽管在这种情况下,悬挂的订阅是无害的,但它们仍然很讨厌。让我感到恼火的是,无论是vb.net还是C#都没有提供一种方便的方法来取消所有已连接的事件的订阅。 - supercat

1

这是一种不使用处理程序变量的替代方法。

Public Class A
{

 public A()
  {

    B_Object.DataLoaded += (sender, e) =>
                {
                   Line 1
                   Line 2
                   Line 3
                   Line 4
                };
  }

  Public override void Dispose()
  {
   if(B_Object.DataLoaded != null)
   {
     B_Object.DataLoaded -=
         (YourDelegateType)B_Object.DataLoaded.GetInvocationList().Last();
       //if you are not sure that the last method is yours than you can keep an index
       //which is set in your ctor ...
   }
  }
 }

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接