最近在Windows server 上要做一个长时间的定时器, 就是每天凌晨 0 点的时候, 执行一个 url 调用, 说道这里, 可能很多朋友会说, 为什么不采用 windows 的计划任务, 我还真用了, 我一共是要3个 任务需要调用, 他们有先后顺序, 结果是, 正常执行了几天, 3个任务中有1个出现了没调用的情况, 因为每次调用了, 我都会写入数据库, 可以肯定就是没调, 至于什么原因, 我真的没有那么多时间跟它折腾, 因为已经在试运营. 所以决定采用C# 定时器来做, 之前用nodejs 定时每天凌晨执行, 也很正常, 所以应该问题不大, 结果却大出意外,
前后使用了C#的 4种定时器:
1. System.Timers.Timer
2. System.Threading.Timer
3. System.Windows.Forms.Timer
我这个是写了一个 C# console, 上面第3种就没用,
我一共用了3太电脑做测试, 边用边测试. 第1, 2 种, 定的是0点, 结果是23:55 就执行了, 提前了5分钟, 当然, 只有阿里云的 Windows server 是这样, 另两台测试正常, 我开始认为是代码写的有问题, 定时器重复调用了, 经过反复测试, 确定是系统的误差, 改成1小时执行一次, 阿里云这台也会有50秒的误差, 没办法, 我想到我自己以前写过一个定时器, 使用的 System.Environment.TickCount
结果一样有误差. 没办法只好使用: Datetime.Now.ticks , 但是这个值太大, 需要用64位保存, 我以前的代码都是用的 float, 只好 用 0xFFFFFFFFFF 去与, 然后 float 就能保存了, 然后继续定时, 发现没有任何误差.
结论是:
C# 的 System.Timers.Timer , System.Threading.Timer, System.Environment.TickCount 在某些机器上存在较大误差, 如果是时间超过1个小时, 对精度要求比较高的定时器只能使用 Datetime.Now.ticks 来做定时器, 前后测试排查用了十几天时间, 希望大家少走弯路.