我正在尝试实施时间服务,报告时间的准确度超过1毫秒。我认为一个简单的解决方案是进行初始测量并使用StopWatch为其添加增量。问题是这种方法似乎与墙壁时间相差很快。例如,以下代码尝试测量Wall Time和我的高分辨率时钟之间的差异:
public static void Main(string[] args)
{
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
DateTime baseDateTime = DateTime.UtcNow;
s.Start();
long counter = 0;
while(true)
{
DateTime utcnow = DateTime.UtcNow;
DateTime hpcutcnow = baseDateTime + s.Elapsed;
Console.WriteLine(String.Format("{0}) DT:{1} HP:{2} DIFF:{3}",
++counter, utcnow, hpcutcnow, utcnow - hpcutcnow));
Thread.Sleep(1000);
}
}
我在相当近的服务器硬件上以大约2毫秒/分钟的速度发散。
在Windows中是否还有其他时间设施我不知道会更准确?如果没有,是否有更好的方法来创建我应该使用的高分辨率时钟或第三方库?
答案 0 :(得分:8)
难以获得准确的时钟。秒表具有非常高的分辨率,但它不准确,从芯片组中的信号中获得其频率。它以典型的电子部件公差运行。硬件业务的激烈竞争优先于昂贵的晶体振荡器,其频率保证稳定。
DateTime.UtcNow也不准确,但它会得到帮助。 Windows会定期联系时间服务,默认情况下是time.windows.com以获取高质量时钟的更新。并使用它来重新校准机器的时钟,插入小的调整以使时钟赶上或减速。
你需要更多更大的技巧才能将其精确到毫秒级。对于在内核模式下运行的代码,您只能获得类似的保证,以中断优先级运行,因此它不会被其他代码抢占,并且其代码和数据页被锁定,因此无法获得页面错误。商业解决方案使用GPS无线电读取GPS卫星的时钟信号,由在烘箱中运行的振荡器支持以提供温度稳定性。读取这样一个时钟是一个难题,当你使用它的程序可以被操作系统抢占时,你不会对亚毫秒时钟源有太多用处,就像它获得时间而不是开始运行一样再次直到~45毫秒后。或者更糟。
由于时间服务更新,DateTime.UtcNow精确到15.625毫秒并且在很长时间内保持稳定。低于此值并不是很有意义,您无法在用户模式下获得所需的执行保证以利用它。
答案 1 :(得分:4)
显然,在Windows 8 / Server 2012中,专门为获取高分辨率时间戳GetSystemTimePreciseAsFileTime API添加了一个新API。我没有机会玩这个,但看起来很有希望。