System.Timers.Timer 已过事件过早触发
System.Timers.Timer elapsed event fires too early
我 运行 遇到了 Elapsed 事件在间隔之前触发的问题。我将间隔设置为 .. 10000 毫秒,事件将在大约 4500 毫秒时触发。我知道这个特定的计时器不太精确,但我确实知道它比它显示的要精确得多。
我已检查以确保调用此事件的计时器不超过一个。此解决方案在安装它的三台 windows 机器中的两台上完美运行。
会不会是.net版本、clr版本等问题
我知道还有其他方法可以完成此操作,但我只是在寻找有关可能导致此功能仅在 3 台服务器中的 2 台上运行的建议。
下面我在服务启动时只创建一次计时器..
checkTimer = new System.Timers.Timer(getSecondsLeft());
checkTimer.Elapsed += checkNowEvent;
checkTimer.AutoReset = true;
checkTimer.Enabled = true;
这里是用来计算到下一分钟的毫秒数的方法
private double getSecondsLeft()
{
DateTime now = DateTime.Now;
// Has a chance to trigger a few milliseconds before new minute. Added 50ms to interval
return ((60 - now.Second) * 1000 - now.Millisecond) + 50;
}
最后是经过时间事件。
private void checkNowEvent(object sender, ElapsedEventArgs e)
{
try
{
// Stop timer to keep from firing this event again
checkTimer.Enabled = false;
// DOING WORK HERE
}
finally
{
// Set the interval as to tick on the start of the next minute
checkTimer.Interval = getSecondsLeft();
// Start timer again
checkTimer.Enabled = true;
}
}
我刚刚对此进行了更多测试,并添加了一些秒表功能,以查看间隔是否真正按预期触发,并且看起来确实如此。然而,当我计算到下一分钟的正确毫秒数时,它的表现就好像这个 Timer 的实现比系统时钟快 运行 ......如果这有意义的话。
这是我用来找出答案的代码。
private void checkNowEvent(object sender, ElapsedEventArgs e)
{
stopWatch.Stop();
_Log.LogDebug(stopWatch.Elapsed.ToString());
try
{
// Stop timer to keep from firing this event again
checkTimer.Enabled = false;
// DOING WORK HERE
}
catch (Exception ex)
{
// CATCHING EXCEPTIONS HERE IF ANY
}
finally
{
// Set the interval as to tick on the start of the next minute
checkTimer.Interval = getSecondsLeft();
_Log.LogDebug(checkTimer.Interval.ToString());
// Start timer again
checkTimer.Enabled = true;
stopWatch.Reset();
stopWatch.Start();
}
}
之所以在新的分钟之前触发是因为系统时间有问题。 DateTime.Now returns 到下一分钟的正确毫秒数,但系统时间移动非常缓慢。当我用秒表验证时,计时器实现似乎工作正常。我刚刚将系统时间与其他两台工作电脑同步,但 5 分钟后又慢了几分钟。
我 运行 遇到了 Elapsed 事件在间隔之前触发的问题。我将间隔设置为 .. 10000 毫秒,事件将在大约 4500 毫秒时触发。我知道这个特定的计时器不太精确,但我确实知道它比它显示的要精确得多。
我已检查以确保调用此事件的计时器不超过一个。此解决方案在安装它的三台 windows 机器中的两台上完美运行。
会不会是.net版本、clr版本等问题
我知道还有其他方法可以完成此操作,但我只是在寻找有关可能导致此功能仅在 3 台服务器中的 2 台上运行的建议。
下面我在服务启动时只创建一次计时器..
checkTimer = new System.Timers.Timer(getSecondsLeft());
checkTimer.Elapsed += checkNowEvent;
checkTimer.AutoReset = true;
checkTimer.Enabled = true;
这里是用来计算到下一分钟的毫秒数的方法
private double getSecondsLeft()
{
DateTime now = DateTime.Now;
// Has a chance to trigger a few milliseconds before new minute. Added 50ms to interval
return ((60 - now.Second) * 1000 - now.Millisecond) + 50;
}
最后是经过时间事件。
private void checkNowEvent(object sender, ElapsedEventArgs e)
{
try
{
// Stop timer to keep from firing this event again
checkTimer.Enabled = false;
// DOING WORK HERE
}
finally
{
// Set the interval as to tick on the start of the next minute
checkTimer.Interval = getSecondsLeft();
// Start timer again
checkTimer.Enabled = true;
}
}
我刚刚对此进行了更多测试,并添加了一些秒表功能,以查看间隔是否真正按预期触发,并且看起来确实如此。然而,当我计算到下一分钟的正确毫秒数时,它的表现就好像这个 Timer 的实现比系统时钟快 运行 ......如果这有意义的话。
这是我用来找出答案的代码。
private void checkNowEvent(object sender, ElapsedEventArgs e)
{
stopWatch.Stop();
_Log.LogDebug(stopWatch.Elapsed.ToString());
try
{
// Stop timer to keep from firing this event again
checkTimer.Enabled = false;
// DOING WORK HERE
}
catch (Exception ex)
{
// CATCHING EXCEPTIONS HERE IF ANY
}
finally
{
// Set the interval as to tick on the start of the next minute
checkTimer.Interval = getSecondsLeft();
_Log.LogDebug(checkTimer.Interval.ToString());
// Start timer again
checkTimer.Enabled = true;
stopWatch.Reset();
stopWatch.Start();
}
}
之所以在新的分钟之前触发是因为系统时间有问题。 DateTime.Now returns 到下一分钟的正确毫秒数,但系统时间移动非常缓慢。当我用秒表验证时,计时器实现似乎工作正常。我刚刚将系统时间与其他两台工作电脑同步,但 5 分钟后又慢了几分钟。