【问题标题】:Stopping A Timer And Preventing The Elapsed Event To Fire停止计时器并防止已逝事件触发
【发布时间】:2012-11-30 22:11:56
【问题描述】:

来自 MSDN:

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

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

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

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

**编辑**

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

没有工作

【问题讨论】:

  • 在设置标志之前尝试测试定时器状态。
  • 您可以随时处理当前计时器并创建一个新计时器以防止旧事件触发。
  • 我遇到了你提到@CSharpDev的同样问题,你在这方面有什么进展吗?

标签: c# winforms multithreading timer


【解决方案1】:
        Timer t = new Timer(4000);
        t.Elapsed += t_Elapsed;
        t.Stop();
        t.Dispose();

最后一行会去掉定时器,这样已经过去的事件就不会发生了。

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

【讨论】:

    【解决方案2】:

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

    //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)检查,则再次启用它。因此,我通过添加额外的标志检查来防止您的问题。

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

    【讨论】:

      猜你喜欢
      • 2015-03-18
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多