We help IT Professionals succeed at work.

C# Remove Elapsed Event Handler From Timer Object

ExcUsr2008
ExcUsr2008 asked
on
I'm doing some server side programming and trying to REUSE a System.Timers.Timer object without luck.

Here is what I want to be able to accomplish

 
System.Timers.Timer myTimer = new System.Timers.Timer(1000);
myTimer.AutoReset = false;
myTimer.Elapsed += delegate { OnMyTimer_Elapsed1(arg1,arg2);};//Yes I need to pass some args which are optional by the way

//then do some processing (this may take 500ms to 2000 ms)

If(something == true){
    //remove previous elapsed event handler from myTimer object
    myTimer.Elapsed -= delegate { OnMyTimer_Elapsed1();};//Notice -=

    //Then reattach different elapsed event handler
    myTimer.Elapsed += delegate { OnMyTimer_Elapsed2(arg1,arg2);}; 
}

Open in new window

This code compiles fine but OnMyTimer_Elapsed1 event is firing TWICE when “something == true” where I was expecting that to be fired only ONCE in any case.

As you can see I'm trying to remove the event handler with "-=" without luck. Your assistance is much appreciated! thanks.
Comment
Watch Question

CERTIFIED EXPERT
Most Valuable Expert 2011
Top Expert 2015
Commented:
Delegates are themselves objects. When you use the delegate keyword, you are creating a new object. You should maintain a scoped reference to the original handler. Try:

System.Timers.Timer myTimer = new System.Timers.Timer(1000);
myTimer.AutoReset = false;
Action handler = delegate { OnMyTimer_Elapsed1(arg1,arg2);};//Yes I need to pass some args which are optional by the way
myTimer.Elapsed += handler;

//then do some processing (this may take 500ms to 2000 ms)

If(something == true){
    //remove previous elapsed event handler from myTimer object
    myTimer.Elapsed -= handler;//Notice -=

    //Then reattach different elapsed event handler
    myTimer.Elapsed += delegate { OnMyTimer_Elapsed2(arg1,arg2);}; 
}

Open in new window

Author

Commented:
Ah ... I completely ignored the context/scope (i.e it needs a reference).

I just had to tweak the code as below since "Action" is not a valid type in this case:

System.Timers.ElapsedEventHandler handler = delegate { OnMyTimer_Elapsed1(arg1,arg2);};


Other than that it worked like a charm!. Many thanks to you!!!