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 分钟后又慢了几分钟。