C#中的计时器运行一次,然后再运行X秒

时间:2011-12-29 23:48:39

标签: c# timer

我有一些代码,其中定时器EventHandler有这个

void timer_Tick(object sender, EventArgs e)
{
    try
    {
         timerRescan.Stop();
         ScanForIeInstances()
    }
    catch (Exception ex)
    {
         log.Warn("Exception 3", ex);
    }
    finally
    {
        timerRescan.Start();
    }
}

当然,有一个外部实体可能想要停止计时器的竞争条件....如果计时器正在进行并且使用某个线程并且有人调用timerRescan.Stop,则计时器线程将调用Start启动计时器再次备份。我正在尝试替换此代码。我知道java中有两种方法,我想知道如何在C#

中做两种方法
  1. 每5秒运行一次任务,其中5秒是任务触发之间的距离
  2. 运行任务并在结束后+ 5秒再次运行任务
  3. 我想使用#2并始终从事件最后一次触发的END开始5秒。我如何做到这一点,我在C#中使用哪个计时器?

    这允许我有一个定期计时器,一次调用启动并且没有停止的竞争条件(我宁愿不必实现同步,但我知道我可以做到这一点作为最后的手段...宁愿只是保持代码清洁,就像我在java中一样)

    或者如果你了解java,我只是在寻找相当于的东西 ScheduledExecutorService.scheduleAtFixedRate - 开始吧 ScheduledExecutorService.scheduleWithFixedDelay - 结束开始

2 个答案:

答案 0 :(得分:2)

处理此问题的一种快速方法是让外部实体设置一个标志,然后检查是否已设置该标志:

public bool StopRequested {get; set;}

void timer_Tick(object sender, EventArgs e)
{
    if (timerRescan != null) timerRescan.Stop();
    if (StopRequested) return;
    try
    {
         ScanForIeInstances()
    }
    catch (Exception ex)
    {
         log.Warn("Exception 3", ex);
    }
    finally
    {
        timerRescan.Start();
    }
}

如果外部实体在计时器上有句柄,这不能解决问题,但计时器应该是私有的。

答案 1 :(得分:0)

如果你唯一担心的是外部资源可能想要停止计时器,你最好的办法就是在这个计时器周围写一个包装器来检查各种各样的信号量....

我没有对此进行任何测试,但你应该能够掌握一般的想法。

public class TimerWrapper
{
  public event EventHandler Elapsed;
  private System.Timers.Timer timer;
  private System.Threading.ManualResetEvent stopped;
  private object lockObject = new object();

  public TimerWrapper(double interval)
  {
    stopped = new System.Threading.ManualResetEvent(false);
    timer = new System.Timers.Timer(interval);
    timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    timer.Start();
  }

  void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  {
    lock (lockObject)
    {
      timer.Stop();
      try
      {
        Elapsed(this, new EventArgs());
      }
      finally
      {
        if (!stopped.WaitOne(0)) timer.Start();
      }
    }
  }

  public void Start()
  {
    stopped.Reset();
    lock (lockObject)
    {
      timer.Start();
    }
  }

  public void Stop()
  {
    stopped.Set();
    lock (lockObject)
    {
      timer.Stop();
    }
  }
}