How to Unregister 'Anonymous' Event Handler

How to remove a lambda event handler

The C# specification explicitly states (IIRC) that if you have two anonymous functions (anonymous methods or lambda expressions) it may or may not create equal delegates from that code. (Two delegates are equal if they have equal targets and refer to the same methods.)

To be sure, you'd need to remember the delegate instance you used:

EventHandler handler = (s, e) => MessageBox.Show("Woho");

button.Click += handler;
...
button.Click -= handler;

(I can't find the relevant bit of the spec, but I'd be quite surprised to see the C# compiler aggressively try to create equal delegates. It would certainly be unwise to rely on it.)

If you don't want to do that, you'll need to extract a method:

public void ShowWoho(object sender, EventArgs e)
{
MessageBox.Show("Woho");
}

...

button.Click += ShowWoho;
...
button.Click -= ShowWoho;

If you want to create an event handler which removes itself using a lambda expression, it's slightly trickier - you need to refer to the delegate within the lambda expression itself, and you can't do that with a simple "declare a local variable and assign to it using a lambda expression" because then the variable isn't definitely assigned. You typically get around this by assigning a null value to the variable first:

EventHandler handler = null;
handler = (sender, args) =>
{
button.Click -= handler; // Unsubscribe
// Add your one-time-only code here
}
button.Click += handler;

Unfortunately it's not even easy to encapsulate this into a method, because events aren't cleanly represented. The closest you could come would be something like:

button.Click += Delegates.AutoUnsubscribe<EventHandler>((sender, args) =>
{
// One-time code here
}, handler => button.Click -= handler);

Even that would be tricky to implement within Delegates.AutoUnsubscribe because you'd have to create a new EventHandler (which would be just a generic type argument). Doable, but messy.

How do I Unregister 'anonymous' event handler

If you need to unregister an event, I recommend avoiding anonymous delegates for the event handler.

This is one case where assigning this to a local method is better - you can unsubscribe from the event cleanly.

Adding and Removing Anonymous Event Handler

There's an MSDN page that talks about this:

How to Subscribe to and Unsubscribe from Events

Note in particular:

If you will not have to unsubscribe to [sic]
an event later, you can use the
addition assignment operator (+=) to
attach an anonymous method to the
event.

And also:

It is important to notice that you
cannot easily unsubscribe from an
event if you used an anonymous
function to subscribe to it. To
unsubscribe in this scenario, it is
necessary to go back to the code where
you subscribe to the event, store the
anonymous method in a delegate
variable, and then add the delegate to
the event . In general, we recommend
that you do not use anonymous
functions to subscribe to events if
you will have to unsubscribe from
the event at some later point in your
code.

Removing an anonymous event listener

There is no way to cleanly remove an event handler unless you stored a reference to the event handler at creation.

I will generally add these to the main object on that page, then you can iterate and cleanly dispose of them when done with that object.

How can an anonymous event handler unregister itself?

Maybe:

RoutedEventHandler handler = null;

Unsubscribe anonymous method in C#

Action myDelegate = delegate(){Console.WriteLine("I did it!");};

MyEvent += myDelegate;

// .... later

MyEvent -= myDelegate;

Just keep a reference to the delegate around.

Removing anonymous event handler

You can refer to your anonymous method from inside itself as long as you assign a delegate to a variable first:

EventHandler<SomeEventArgs> handler = null;
handler = (s, e) =>
{
_client.AddMemberToTeamCompleted -= handler;
callback(e.Result);
};

_client.AddMemberToTeamCompleted += handler;

Note that you need to declare the variable and assign it separately or the compiler will deem it uninitialized when you come to use it inside the method body.

Removing anonymous event handlers with some parameters

it will not work cause drawEvent is local variable and next time I call CoupleOverlay, it will create new one.

Indeed. You'd basically need to keep an instance variable instead of a local variable. The instance variable would effectively be "the currently subscribed event handler". Then in CoupleOverlay you'd remove that event handler, create a new one (storing it in the variable) and resubscribing with it.

An alternative would be to use a single event handler, but keep the "current" overlay and map visual as instance variables, used by the event handler. The CoupleOverlay method would then just need to update those variables.



Related Topics



Leave a reply



Submit