【问题标题】:Do you need to "unwire" an anonymous function/lambda您是否需要“取消连接”匿名函数/lambda
【发布时间】:2011-06-09 10:35:06
【问题描述】:

我的理解是,在 C# 中连接的任何事件处理程序都需要这样取消连接。

Object myObject = new Object();
myObject.Event += EventHandler; //Wired
myObject.Event -= EventHandler; //Unwired

但是您需要取消连接以下代码吗?如果有,怎么做?

Object myObject = new Object();
myObject.Event += (object sender, EventArgs e) => { }; //Wired
myObject.Event -= ????? //Unwire? How?

我的假设是否定的?

【问题讨论】:

  • 您能否澄清一下您的理解是什么?您所说的“需要成为”是什么意思?

标签: c# events lambda event-handling anonymous-function


【解决方案1】:

是的,你需要 (*) 并且你需要这样做:

Object myObject = new Object();
EventHandler handler = (object sender, EventArgs e) => { };
myObject.Event += handler; //Wired
myObject.Event -= handler; //Unwired

请参阅here 了解说明。

(*)
由于垃圾收集,您不需要这样做。如果您不想让事件再调用您的处理程序,您需要这样做。

更新:
澄清一下:
您想要取消连接事件处理程序的唯一原因是定义事件处理程序的对象可以被垃圾收集。
想想下面的例子:

  • 你有一个班级 PowerSource 和一个事件 BlackOut
  • 只要有电,您就有一个课程LightBulb。它有一个方法ConnectToPowerSource。此方法订阅提供的PowerSourceBlackOut 事件。
  • 您有一个包含灯泡的集合

现在,简单地从列表中删除一个灯泡不会使其被垃圾收集,因为PowerSource 在其BlackOut 事件中仍然持有对LightBulb 实例的引用。只有在从BlackOut 事件中注销LightBulb 后,LightBulb 才会被垃圾回收。

【讨论】:

  • +1 表示 (*)。因为您永远必须解线,所以您要么需要,要么不需要。
  • 你的(*)这句话是什么意思?只要事件处理程序存在,它就会阻止收集所有捕获的局部变量。因此,由于 GC,您也需要这样做(至少如果事件的发布者比消费者的寿命长得多)。当然,最常见的拆线原因是您不想再调用您的事件处理程序。 (我不是反对者)
  • 我的意思是:如果不再需要 myObject 并且所有引用都消失了,它将被垃圾收集,以及分配给其事件处理程序的匿名方法。如果 myObject 仍在使用,但您不希望您的特定事件处理程序不再被调用,则需要取消连接它,如果不再保存对它的引用,这将导致它的垃圾收集。我想,我想说的是:你不需要拆线,myObject 被收集。但这实际上与匿名方法无关,所有事件处理程序都是如此。
【解决方案2】:

是的,你必须这样做。因为事件是强引用,所以您的事件处理程序将继续被调用。

您可以按如下方式删除它:

EventHandler handler = (s,e) => { DoSomething(); }
myObject.Event += handler; 
myObject.Event -= handler; 

【讨论】:

  • 如果您希望停止调用处理程序,您必须这样做。如果您不在乎,则不必。
【解决方案3】:
Object myObject = new Object();
EventHandler h = (object sender, EventArgs e) => { }; //Wired
myObject.Event += h;
myObject.Event -= h;

或者,在处理程序中取消连接:

Object myObject = new Object();
EventHandler h = null; //need to declare h to use it in the following line
//compiler/resharper will complain about modified closure
h = (object sender, EventArgs e) => { myObject.Event-=h; };
myObject.Event += h;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-23
    • 2017-07-25
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    相关资源
    最近更新 更多