【发布时间】: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 秒的延迟对于计时器来说很长,我认为操作系统应该以某种方式处理这个问题。
-
如果程序每隔几秒就处于活动状态,则不应出现分页。此外,如果没有内存压力,在激活每天仅活动一次的程序部分时,您将看到接近于零的延迟。 是否有内存压力?