简体   繁体   English

停止计时器并防止发生经过的事件

[英]Stopping A Timer And Preventing The Elapsed Event To Fire

From MSDN: 从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. 在ThreadPool线程上引发Timer.Elapsed事件,因此事件处理方法可能在一个线程上运行,而对Timer.Stop方法的调用在另一个线程上运行。 This might result in the Elapsed event being raised after the Stop method is called.. 这可能导致在调用Stop方法之后引发Elapsed事件。

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. 如果在调用stop和dispose时计时器已经在执行过去的函数,则执行将完成。

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. 假设try块中的代码花费更多时间。 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. 因此,当您禁用计时器时(_timer.Enabled = false or _timer.Stop()) ,很有可能try块中的代码仍在执行。 Hence, after completion of the task when it comes to finally, it is again enabled if there is no flag( _shouldEnableTimer ) check. 因此,在完成最后的任务后,如果没有标志( _shouldEnableTimer )检查,则会再次启用它。 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. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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