如何取消注册我的Lambda回调?

时间:2011-04-26 22:42:52

标签: c# events lambda callback

如果我创建一个lambda回调,例如:

var someInstance = new SomeObject();

someInstance.Finished += (obj, args) =>
{
      // Do something

      // Deregister here
};

someInstance.DoAction();

如何将回调注销为实际处理程序代码的一部分?这种模式是理想的,因为我可以确保它尽快释放。

我见过类似的问题,但没有直接解决此类示例的问题。

5 个答案:

答案 0 :(得分:6)

有类似的东西,

var someInstance = new SomeObject();

EventHandler myDelegate = null;
myDelegate = (obj, args) =>
{
      // Do something

      // Deregister here
      someInstance.Finished -= myDelegate;
};
someInstance.Finished += myDelegate;

someInstance.DoAction();

答案 1 :(得分:5)

如果您想要取消注册,那么最好将您的lambda定义为Action,以便您可以写:

someInstance.Finished += MyCustomAction;

以后

someInstance.Finished -= MyCustomAction;

答案 2 :(得分:5)

您可以在lambda中使用MethodInfo.GetCurrentMethod来检索lambda的MethodInfo。

使用MethodInfo,您可以使用Delegate.CreateDelegate来获取代表lambda的正确类型的委托。

使用委托,您可以取消注册lambda,而无需将函数存储在变量中或使其成为命名方法。

class MyClass 
{
    public event EventHandler TheEvent;

    void TestIt()
    {
        TheEvent += (sender, eventargs) => 
            {
            Console.WriteLine("Handled!"); // do something in the handler

            // get a delegate representing this anonymous function we are in
            var fn = (EventHandler)Delegate.CreateDelegate(
                             typeof(EventHandler), sender, 
                             (MethodInfo)MethodInfo.GetCurrentMethod());

            // unregister this lambda when it is run
            TheEvent -= fn;
        };


        // first time around this will output a line to the console
        TheEvent(this, EventArgs.Empty);

        // second time around there are no handlers attached and it will throw a NullReferenceException
        TheEvent(this, EventArgs.Empty);
    }

}

答案 3 :(得分:1)

如果您想在之后删除事件处理程序,则应使用命名函数:

  someInstance.Finished += HandleFinished;

  //...
  void HandleFinished(object sender, EventArgs args) 
  {  
    someInstance.Finished -= HandleFinished;
  }

答案 4 :(得分:1)

这似乎有效:

EventHandler handler = null;
handler = new EventHandler((sender, e) => SomethingHappened -= handler);
SomethingHappened += handler;

请确保您没有将handler分配给任何其他值,因为闭包与该变量相关联。这就是Resharper抱怨的“获得修改后的关闭”。