1

来自 MSDN:

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

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

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

如何停止标志并确保已逝事件不会触发?

**编辑**

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

都不工作

4

2 回答 2

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

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

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

于 2012-11-30T23:34:03.143 回答
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(_timer.Enabled = false or _timer.Stop())时,try 块内的代码很有可能仍在执行。因此,在finally任务完成后,如果没有flag( _shouldEnableTimer)检查,则再次启用。因此,我通过添加额外的标志检查来防止您的问题。

为了更清楚,请仔细阅读代码和添加的注释。希望这可以帮助。

于 2018-09-05T11:32:31.017 回答