【问题标题】:How to unsubscribe an anonymous function in Dispose method of a class?如何取消订阅类的 Dispose 方法中的匿名函数?
【发布时间】:2012-04-02 11:15:36
【问题描述】:

我有一个 A 类...在它的构造函数中...我正在为 Object_B 的 eventHandler 分配一个匿名函数。

如何从 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 以外的任何地方访问;它可能有其他听众吗?
  • 是的,它是成员...B 类的哪个实例

标签: c# dispose anonymous-function unsubscribe


【解决方案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 ...
   }
  }
 }

【讨论】:

    【解决方案2】:

    正确的方法是使用 Rx Extensions。去这里观看视频:

    http://msdn.microsoft.com/en-us/data/gg577611

    我发现“布鲁斯”电影特别有用。

    【讨论】:

      【解决方案3】:

      你不能,基本上。要么将其移动到方法中,要么使用成员变量来保留委托以供以后使用:

      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:不一定。你还没有真正谈论过B_Object.DataLoaded - 如果那实际上是一个实例事件而不是一个静态事件,那么如果收集了对象,那么事件订阅将不再重要。这一切都取决于上下文......
      • B_Object.DataLoaded 是一个实例事件..不是静态事件。您能否澄清一下:-“如果收集了对象,则事件订阅无关紧要”
      • @Relativity: 如果对象 X 订阅了来自对象 Y 的任何事件但没有取消订阅,则悬空事件将导致对象 X 至少与对象 Y 一样长。对象 Y 将比对象 X 的有用生命周期长得多,这可能是一件坏事。如果在对象 Y 的内存生命周期内,将创建和放弃对象 X 的许多实例,即使不是灾难性的,也可能非常糟糕。但是,如果在时间 X 变得无用时 Y 有资格被收集,则悬空订阅将不会使 X 保持活动状态。
      • @Relativity:尽管在这种情况下悬空订阅是无害的,但它们仍然很恶心。让我很生气的是,vb.net 和 C# 都没有提供一种方便的方式来取消订阅一个附加的所有事件。
      猜你喜欢
      • 2010-09-16
      • 1970-01-01
      • 2018-08-17
      • 2017-04-25
      • 2021-01-28
      • 2011-09-12
      • 2021-06-14
      • 2020-10-20
      • 1970-01-01
      相关资源
      最近更新 更多