在使用Stopwatch.GetTimestamp()时,我们发现如果你记录返回值,然后继续调用它并与之前的返回值进行比较,它最终会不可预测地返回一个小于原始值的值。
这是预期的行为吗?
在生产代码中执行此操作的目的是具有微秒的准确系统时间。
该技术涉及调用DateTime.UtcNow并分别调用Stopwatch.GetTimestamp()作为originalUtcNow和originalTimestamp。
从那时起,应用程序只需调用Stopwatch.GetTimestamp()并使用Stopwatch.Frequency计算与originalTimestamp变量的差异,然后将该差异添加到originalUtcNow。
然后,Voila ......一个高效准确的微秒DateTime。
但是,我们发现有时Stopwatch.GetTimestamp()会返回较低的数字。
这种情况很少发生。我们的想法是在发生这种情况时简单地“重置”并继续。
但是,它让我们怀疑Stopwatch.GetTimestamp()的准确性,或者怀疑.Net库中存在错误。
如果你能对此有所了解,请做。
仅供参考,根据当前的时间戳值,频率和long.MaxValue,它看起来不太可能在我们的生命周期中翻转,除非它是硬件问题。
编辑:我们现在正在计算“每个线程”的值,然后“钳制它”以观察核心之间的跳转以重置它。
答案 0 :(得分:6)
由于您的线程正在跳跃核心,因此您可能会及时获得跳跃。请参阅此页面上的“注释”:http://msdn.microsoft.com/en-us/library/ebf7z0sw.aspx
答案 1 :(得分:2)
秒表类的行为因系统而异,具体取决于硬件支持。
请参阅:http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.ishighresolution.aspx
另外,我认为基础等效的win32调用( QueryPerformanceCounter )包含有用的文档:http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx
答案 2 :(得分:1)
我不确切地知道关于向后跑(这听起来像是小向后改变),但我到目前为止经历了三次,因为Stopwatch.GetTimestamp()的值可以改变所以极大地说,它导致溢出异常进一步计算形式如下:
(Stopwatch.GetTimestamp() - ProgramStartStopwatchTimestamp) * n
其中 n 是一个很大的值,但足够小,如果秒表没有大幅跳跃,那么程序可以运行数年而不会出现溢出异常。另请注意,这些异常是在程序启动后的几个小时内发生的,因此问题不仅仅是Stopwatch在启动后立即向后运行了一小段时间。它只是向任何方向跳到完全不同的范围。
关于秒表滚动,在上述情况之一(不是差异,但秒表)获得了一个la 0xFF4的值? ???? ???? ????,所以它跳到了非常接近翻滚的范围。多次重新启动程序后,这个新范围仍然一直有效。如果重要的是考虑到需要处理跳跃......
如果还需要确定采用时间戳的核心,则可能有助于了解执行核心编号。为此,有一些名为GetCurrentProcessorNumber
的功能(自Server 2003和Vista以来可用)和GetCurrentProcessorNumberEx
(自Server 2008 R2和Windows 7以来可用)。有关更多选项(包括Windows XP),另请参阅this question's answers。
请注意,调度程序可以随时更改核心编号。但是,如果在读取秒表时间戳之前读取核心编号,之后核心编号保持不变,则可能会假设秒表读取也在此核心上执行...
答案 3 :(得分:0)
要专门回答高级问题“ Stopwatch.GetTimestamp()
多久滚动一次?”,Microsoft's answer为:
自最近的系统启动起不少于100年,并且根据所使用的基础硬件计时器,可能会更长。对于大多数应用程序而言,无需担心过渡问题。