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

时间:2012-11-30 22:11:56

标签: c# winforms multithreading timer

来自MSDN:

  

在ThreadPool线程上引发Timer.Elapsed事件,因此事件处理方法可能在一个线程上运行,同时调用Timer.Stop方法在另一个线程上运行。这可能导致在调用Stop方法后引发Elapsed事件。

我有一个运行特定时间的计时器,然后过去并设置一个标志。有时我想停止计时器并重新启动它。

目前,当我尝试停止计时器时,经过的事件仍然会触发(有时),所以当我不想要它时,我的标志就会被设置。

如何停止标记并确保已经过的事件不会触发?

**编辑**

在事件处理程序中,我已经尝试检查计时器的状态以确保在运行代码之前启用它,并且我还尝试在停止计时器并在运行代码之前检查该标志时设置标志。 / p>

既不工作

2 个答案:

答案 0 :(得分:0)

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

最后一行将删除计时器,以便不会发生经过的事件。

如果在调用stop和dispose时计时器已经执行了已运行的函数,则执行将完成。

答案 1 :(得分:0)

我也多次遇到类似的问题。

//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;

为什么这样做?

让我们假设,try块中的代码会花费更多时间。因此,当您禁用计时器(_timer.Enabled = false or _timer.Stop())时, try块中的代码仍在执行的可能性。因此,在完成最后的任务后,如果没有标志(_shouldEnableTimer)检查,则会再次启用。因此,我通过添加其他标志检查来防止出现您的问题。

为更清楚起见,请遍历代码和添加的注释。希望这可以帮助。