Baptiste Pernet
Baptiste Pernet

Reputation: 3384

Detaching an handler the first time you call it

I would like to call the event handler just one time, and then detach it. I tried to write:

EventHandler handler = (s, e) =>
{
    // Do something
    //
    // blabla

    // Detach the handler
    SizeChanged -= handler;
};
SizeChanged += handler;

However on the line SizeChanged -= handler I get this error

Use of unassigned local variable 'handler'

Do you have idead on how I should proceed ? I thought about using a boolean flag, but I will do that only if I can't find a way to detach the handler.

Upvotes: 3

Views: 184

Answers (2)

YoryeNathan
YoryeNathan

Reputation: 14512

This is because it really is unassigned yet. Try making a named method out of it, so the symbol is known prehand.

private void OnEvent(object sender, EventArgs e)
{
    // Do something

    AnEvent -= OnEvent;
}

private void RegisterOnce()
{
    AnEvent += OnEvent;
}

I would also recommend to run the DoSmething code only after detatch and implement some locking mechanism, in case you have multithrading, to prevent from multiple threads call the event at the exact same time, not having time to detatch and therefore, all run.

Upvotes: 3

aKzenT
aKzenT

Reputation: 7895

The C# compiler will first create the lambda expression you wrote before assigning the result to the variable. So when the lambda is defined, handler doesn't have a value.

It works though if you assign a value of null to EventHandler before.

Since it's a closure and local variables are captured in the closure, at the time of the call handler will have the correct value and it will work:

        EventHandler handler=null;

        handler = (s, e) =>
        {
            // Do something 
            SizeChanged -= handler;
        };
        SizeChanged += handler; 

To all people downvoting: It won't cause a NullReferenceException. handler is a local variable which is captured in the closure, so the value of handler inside the lambda will change, when it changes in the method that contains the closure. I tested it actually on my PC and it works perfectly.

Upvotes: 6

Related Questions