【问题标题】:Every morning Timers.Timer is late for 2-5 seconds每天早上 Timers.Timer 迟到 2-5 秒
【发布时间】:2014-05-27 16:14:34
【问题描述】:

我有一个System.Timers.Timer,用于安排一些任务的运行。我有两个 BlockingCollection 队列正在等待计时器触发并将一些任务放入队列:

private void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
{
   Logger.WriteTrace("Timer elapsed", "Timer elapsed after waiting: "+ DateTime.Now);
   lock (globalLock)
   {
      if (!_stop)
      {
         Logger.WriteTrace("Timer elapsed", "Iterating through schedules");
         DateTime now = DateTime.Now;
         foreach (T schedule in schedules)
         {
            DateTime occurence = schedule.GetNextOccurrence(now);
            if ((occurence - now).TotalMilliseconds < DefaultDelay)
            {
               Logger.WriteTrace("Run times", "Task added to the queue");
               priorityDictionary[schedule.IsParallel].Add(schedule);
            }
         }

         double nextWake = CalcualteNextWake(DateTime.Now.AddMilliseconds(DefaultDelay));
         SetInterval(nextWake);
      }
   }
}

在 SetInterval 方法中我有

if (interval > 0)
{
   _timer.Interval = interval;

   // starting timer, cause by design it is not Autoreset
   Logger.WriteTrace("Setting next wake after: ",
      interval.ToString() + " at " + DateTime.Now.AddMilliseconds(interval));

   _timer.Start();
}
else
{
   Logger.Error("Wrong interval");
}

所以我注意到计时器的奇怪行为,每天写的最后一条日志消息都是这样说的:

12:37:59##Trace####Setting next wake after: ##78839662.0084 at 5/27/2014 10:31:58 AM##

每天第一条消息说:

10:32:03##Trace####Timer elapsed##Timer elapsed after waiting: 5/27/2014 10:32:03 AM##

计时器的每隔一段时间运行良好且准确,并且与“设置下一次唤醒”消息中所说的时间完全相同,因此计时器仅在每天第一次运行时才延迟,并且始终在 2-5 秒之间。我在代码中找不到任何可能成为问题的东西,似乎它运行良好,而且白天计时器过去没有任何问题。有人对导致此问题的原因有什么想法吗?

谢谢。

【问题讨论】:

  • 我认为这不是问题所在,但您应该真正使用 UtcNow。还是您的代码能容忍时钟每年跳动两次?
  • 当你的程序长时间不执行代码时,操作系统对你的程序并不友好。几乎每个内存页面都会从 RAM 中换出。从 DLL 文件和分页文件加载它可能需要一段时间。功能,而不是错误。
  • usr:我应该使用 UtcNow,没错。
  • Hans Passant:我想过,但有办法避免吗?或要求操作系统按照我的需要行事? 5 秒的延迟对于计时器来说很长,我认为操作系统应该以某种方式处理这个问题。
  • 如果程序每隔几秒就处于活动状态,则不应出现分页。此外,如果没有内存压力,在激活每天仅活动一次的程序部分时,您将看到接近于零的延迟。 是否有内存压力?

标签: c# timer


【解决方案1】:

好吧,在您的代码中,您在 Logger.WriteTrace 中使用 DateTime.Now

为什么不创建一个变量并像这样使用它

DateTime now = DateTime.Now;

Logger.WriteTrace("Timer elapsed", "Timer elapsed after waiting: "+ now);

同样在 SetInterval 方法中

Logger.WriteTrace("Setting next wake after: ",
      interval.ToString() + " at " + now.AddMilliseconds(interval));

【讨论】:

  • 这不是我的问题的答案,我更改它只是为了能够知道添加到队列的操作时间,以防万一。
猜你喜欢
  • 2022-01-12
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
  • 2017-08-01
相关资源
最近更新 更多