简体   繁体   中英

Stopping A Timer And Preventing The Elapsed Event To Fire

From MSDN:

The Timer.Elapsed event is raised on a ThreadPool thread, so the event-handling method might run on one thread at the same time that a call to the Timer.Stop method runs on another thread. This might result in the Elapsed event being raised after the Stop method is called..

I have a timer that runs for a specific time then elapses and sets a flag. Sometimes I want to stop the timer and restart it.

Currently when I try to stop the timer, the elapsed event still fires (sometimes), so my flag is set when I don't want it to be.

How do I stop the flag and be sure the elapsed event doesn't fire?

**EDIT**

In the event handler, I've tried checking the timer's state to ensure its enabled before I run the code, and I've also tried setting a flag when I stop the timer and checking that flag before running the code.

Neither work

        Timer t = new Timer(4000);
        t.Elapsed += t_Elapsed;
        t.Stop();
        t.Dispose();

the last line will remove the timer, so that the elapsed event can not happen.

If the timer is already executing the elapsed function when stop and dispose are called, the execution will complete.

I also ran into the similar problem many times.

//Timer init.
 var _timer = new System.Timers.Timer
{
    AutoReset = true, 
    Enabled = true,
    Interval = TimeSpan.FromSeconds(15).TotalMilliseconds //15 seconds interval
};
 _timer.Elapsed += DoSomethingOnTimerElapsed;


//To be called on timer elapsed.
private void DoSomethingOnTimerElapsed(object source, ElapsedEventArgs e)
{
    //Disable timer.
    _timer.Enabled = false; //or _timer.Stop()
    var markers = new Dictionary<string, ConversationItem>();
    try
    {
        //does long running process
    }
    catch (Exception ex)
    {

    }
    finally
    {
        if (_shouldEnableTimer) //set its default value to true.
            _timer.Enabled = true; //or _timer.Start()
    }
}


//somewhere in the code if you want to stop timer:
_timer.Enabled = _shouldEnableTimer = false;

//At any point, if you want to resume timer add this:
_timer.Enabled = _shouldEnableTimer = true;

Why to do so?

Lets assume, the code inside the try block takes more time. So, by the time you disable timer (_timer.Enabled = false or _timer.Stop()) , there is high possibilty that the code inside try block is still executing. Hence, after completion of the task when it comes to finally, it is again enabled if there is no flag( _shouldEnableTimer ) check. Therefore, I prevent your problem by adding an additional flag check.

For more clarity, please go through the code and the added comments. Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM