6

在使用 Stopwatch.GetTimestamp() 时,我们发现如果您记录返回值,然后继续调用它并与之前的返回值进行比较,它最终会但不可预测地返回一个小于原始值的值。

这是预期的行为吗?

在生产代码中这样做的目的是获得微秒精确的系统时间。

该技术涉及调用 DateTime.UtcNow 并分别调用 Stopwatch.GetTimestamp() 作为 originalUtcNow 和 originalTimestamp。

从那时起,应用程序只需调用 Stopwatch.GetTimestamp() 并使用 Stopwatch.Frequency 计算与 originalTimestamp 变量的差异,然后将该差异添加到 originalUtcNow。

然后,瞧……一个高效且准确的微秒 DateTime。

但是,我们发现有时 Stopwatch.GetTimestamp() 会返回较小的数字。

它很少发生。我们的想法是在这种情况发生时简单地“重置”并继续。

然而,这让我们怀疑 Stopwatch.GetTimestamp() 的准确性或怀疑 .Net 库中存在错误。

如果你能对此有所了解,请做。

仅供参考,根据当前的时间戳值、频率和 long.MaxValue,除非是硬件问题,否则它似乎不太可能在我们的生命周期内翻转。

编辑:我们现在“每个线程”计算这个值,然后“钳制它”以观察内核之间的跳转以重置它。

4

4 回答 4

6

您可能会及时获得跳跃,因为您的线程正在跳跃核心。请参阅此页面上的“注释”:http: //msdn.microsoft.com/en-us/library/ebf7z0sw.aspx

于 2012-01-24T01:00:49.920 回答
2

Stopwatch 类的行为会因系统而异,具体取决于硬件支持。

请参阅: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

于 2012-01-24T01:01:44.143 回答
1

我不知道关于向后运行的确切信息(这听起来像是一个的向后变化),但到目前为止我已经经历了三倍,Stopwatch.GetTimestamp() 的值可能会发生如此巨大的变化,以至于在一些进一步的计算中会导致溢出异常形式大约是这样的:
(Stopwatch.GetTimestamp() - ProgramStartStopwatchTimestamp) * n
其中n是一个很大的值,但足够小,如果秒表没有大幅跳动,那么程序可以运行数年而不会出现溢出异常。另请注意,这些异常发生在程序启动数小时后,因此问题不仅仅是秒表在启动后立即向后运行。它只是在任何方向上跳到了完全不同的范围。

关于秒表翻转,在上述一种情况下,它(不是差异,而是秒表)获得了 la 0xFF4 的值???????????,所以它跳到了一个非常接近翻滚的范围。多次重新启动程序后,这个新范围仍然有效。如果考虑到无论如何都需要处理跳跃,这不再重要......

如果还需要确定时间戳是在哪个内核上进行的,那么了解正在执行的内核编号可能会有所帮助。为此,有称为GetCurrentProcessorNumber(自 Server 2003 和 Vista 起GetCurrentProcessorNumberEx可用)和(自 Server 2008 R2 和 Windows 7 起可用)的函数。另请参阅此问题的答案以获取更多选项(包括 Windows XP)。
请注意,调度程序可以随时更改核心编号。但是,如果在读取秒表时间戳之前和之后读取核心编号,并且核心编号保持不变,那么也许可以假设秒表读取也在此核心上执行......

于 2013-12-19T16:58:59.653 回答
0

为了具体回答“多久Stopwatch.GetTimestamp()翻一次?”这个高级问题,微软的回答是:

从最近的系统启动起不少于 100 年,并且根据使用的底层硬件计时器可能更长。对于大多数应用程序,翻转不是问题。

于 2020-11-30T21:42:41.103 回答