System.Timers.Timer()由于Elapsed Events的聚合而多次触发

时间:2014-05-25 08:19:42

标签: c#

我希望我的代码的一部分在调用后启动一个计时器,我希望这个计时器继续运行直到我退出整个程序。我的问题是,每当我调用OnSomethingHappens()时,Elapsed事件聚合(尽管我努力使用 - =)并且计时器开始激发一个额外的时间(或者至少这是我认为正在发生的事情)。我也试过在课堂上定义计时器,但没有用。这是我的代码的相关部分:

public override void OnSomethingHappens()
    {
        Timer aTimer= new System.Timers.Timer();
        aTimer.Elapsed -= (sender, e) => DoSomethingElse(sender, e);
        aTimer.Stop();
        aTimer.Close();
        aTimer.Elapsed += (sender, e) => DoSomethingElse(sender, e);
        aTimer.Interval = 1000;
        aTimer.AutoReset = true; // I want the timer to keep working, but only fire once each time
        Console.WriteLine("Enabling Timer aTimer");
        aTimer.Start();
}

我不能使用静态(不确定这会有什么帮助,但我看到定时器在许多来源中被定义为静态)因为这个类有很多实例,我希望它们有不同的定时器。

谢谢。

3 个答案:

答案 0 :(得分:6)

在没有AutoReset的情况下启动计时器,并在DoSomethingElse结束时重新启动计时器。

aTimer.AutoReset = false;
aTimer.Start();

DoSomethingElse(..)
{
   // do stuff here
   aTimer.Start();
}

答案 1 :(得分:3)

如果此类的每个实例都使用自己的计时器,则不需要静态。

    private Timer _aTimer;

    public void OnSomethingHappens()
    {  
        if (_aTimer != null)
        {    
            _aTimer.Enabled = true;  // start timer
            return;
        }

        _aTimer = new System.Timers.Timer();
        _aTimer.Elapsed += DoSomethingElse;
        _aTimer.Interval = 1000; // every 1 second
        _aTimer.Enabled = true;  // start timer
    }

    private void DoSomethingElse(object sender, ElapsedEventArgs e)
    {    
        _aTimer.Enabled = false; // stop timer
        // do w/e you want

    }

答案 2 :(得分:2)

首先,你应该只创建一次计时器实例,并挂钩一个事件监听器。使用当前代码,每次调用方法时,都会创建一个带有事件侦听器的新计时器。而是使计时器成为类变量,并在构造函数中挂钩事件侦听器。

你可以在OnSomethingHappens中启动计时器,但是你想在后续的方法调用中发生什么?计时器重启,还是继续?

你可能还想让类IDisposable,或者至少提供一个Stop方法来在应用程序关闭时停止计时器。

public class MyClass : MyBaseClass, IDisposable
{
   private Timer _timer;
   private volatile bool _isStopped = true;

   public MyClass()
   {
       _timer = new Timer();
       _timer.Interval = 1000;
       _timer.Elapsed = OnTimerElapsed;
   }

   public void Stop()
   {
       _isStopped = true;
       _timer.Stop();
   }

   public void Dispose()
   {
      if (_timer != null)
      {
          Stop();
          _timer = null;
      }
   }

   protected override void OnSomethingHappens()
   {
       if (_timer.Enabled)
       {
          // Restart or do nothing if timer is already running?
       }
       else
       {
          _isStopped = false;
          _timer.Start();              
       }
   }

   private void OnTimerElapsed(object sender, EventArgs a)
   {
      if (_isStopped)
      {
          // If the Stop method was called after the Elapsed event was raised, don't start a long running operation
          return;
      }
   }
}