How do I unregister Lambda?

If I create a lambda callback, for example:

var someInstance = new SomeObject();

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

      // Deregister here
};

someInstance.DoAction();

How can I unregister a callback as part of the actual handler code? This template would be ideal, as I could ensure its release as soon as possible.

I saw similar questions, but not the one where this type of example is directly addressed.

+5
source share
5 answers

You can use MethodInfo.GetCurrentMethodlambda inside your lambda to extract MethodInfo.

With MethodInfo, you can use Delegate.CreateDelegateto get a correctly typed delegate representing your 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);
    }

}
+5

-

var someInstance = new SomeObject();

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

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

someInstance.DoAction();
+6

If you want to unregister, then it's best to define your lambda as an action so you can write:

someInstance.Finished += MyCustomAction;

and later

someInstance.Finished -= MyCustomAction;
+5
source

If you want to remove the event handler later, you should use a named function:

  someInstance.Finished += HandleFinished;

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

It works:

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

Just make sure you are not assigning it to handlerany other value, since the closure is bound to this variable. This is what Resharper complains about as “access to modified closure”.

+1
source

All Articles