【问题标题】:timer.interval increasing interval between callstimer.interval 增加调用之间的间隔
【发布时间】:2019-09-26 03:49:16
【问题描述】:

所以,我设置了一个基本计时器,每分钟唤醒一次 Windows 服务

Timer timer = new Timer();
timer.Interval = 1000 * 60; // 60 seconds
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Start();

它大部分时间都在工作,但我注意到大约每小时它会增加 1 秒内经过时间的间隔:

[...]
Service is recall at 9/25/2019 1:26:52 AM
Service is recall at 9/25/2019 1:27:52 AM
Service is recall at 9/25/2019 1:28:52 AM
Service is recall at 9/25/2019 1:29:52 AM
Service is recall at 9/25/2019 1:30:53 AM
Service is recall at 9/25/2019 1:31:53 AM
Service is recall at 9/25/2019 1:32:53 AM
[...]

这导致服务在分钟更改时跳过服务召回:

Service is recall at 9/20/2019 2:38:59 AM
Service is recall at 9/20/2019 2:40:00 AM

2:39 服务未被召回。

我认为这是因为计时器会在经过一段时间后唤醒,不一定在满足间隔的确切时间,这没关系(我不需要很高的精度,只要每分钟唤醒服务即可) .我只是不希望呼叫之间的间隔每小时增加 1 秒左右。

我试图计算一个新的时间间隔(而不是 60000 毫秒)来纠正经过的时间,但它并不统一。

关于如何防止这种情况发生的任何想法?

【问题讨论】:

  • 你不能相信你的事件处理程序每​​分钟都会被调用一次。更好的方法是使用较小的时间间隔(例如 1 秒)并记住最后一次通话的时间。然后仅当分钟相对于记住的时间戳发生变化时才执行所需的操作。

标签: c# windows-services


【解决方案1】:

计时器按您的预期每分钟触发一次,但计时器没有考虑处理函数中的信息所需的时间。如果您需要它每分钟触发一次,则需要计算处理您的信息所花费的时间,然后更改计时器触发之前的时间量:

private void OnElapsedTime()
{
    Stopwatch watch = new Stopwatch();
    watch.Start();

    //DO YOUR WORK HERE

    Timer.Change(Math.Max(0, 60000 - watch.ElapsedMilliseconds));

    watch.Stop();
}

这不是 100% 精确,但应该会给您想要的结果。

【讨论】:

    猜你喜欢
    • 2018-05-14
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多