DateTime.UtcNow.Ticks有时跳得很多

时间:2008-11-04 20:00:44

标签: .net windows datetime time

在一个打印出DateTime.UtcNow.Ticks值的严密循环测试应用程序中,我注意到每小时左右该值会跳出一次非常大的值。仔细查看以下示例数据:

1:52:14.312 PM - 633614215343125000
1:52:14.359 PM - 633614215343593750
1:52:14.421 PM - 633614215344218750
1:52:14.468 PM - 633614215344687500
1:52:14.515 PM - 633614215998593750 <-- WAY different

delta是653906250 ticks(65.390秒)。我能想到的唯一原因是Windows时间服务正在从我的脚下进行一些同步。

  • 有没有专家可以证实这一点?
  • 大约一个小时左右漂流一分钟对我来说似乎很糟糕,但这就是这种情况吗?

5 个答案:

答案 0 :(得分:2)

实际上,只需使用此循环运行一些测试:

static DateTime past = DateTime.UtcNow;
    static void PrintTime()
    {
        while (stopLoop == 0)
        {
            DateTime now = DateTime.UtcNow;
            Console.WriteLine("{0} - {1} d: {2}", now, now.Ticks, now - past);
            Program.past = now;
            Thread.Sleep(2000);
        }
    }

如果我在两次通话之间更改了系统的时钟时间,则delta会相应地跳转。因此,如果您正在运行时间同步或其他影响系统时间的进程,那么这将反映在输出中。

答案 1 :(得分:1)

...埃姆

如果您无法确定在此期间没有调用某些阻塞系统调用(例如,可能是Console.WriteLine),那么如何以这种方式测量时间?

为了进行“工作测试”,您必须至少确保:

  • 没有其他人在您的计算机上运行
  • 进程/线程优先级设置为“高”或类似
  • 呼叫无系统呼叫...仅执行计算任务
  • 将线程关联设置为特定CPU,以便不在CPU之间切换

即使您这样做,操作系统也会不时(例如Windows双核桌面操作系统上的15毫秒)抢占您的线程.... 你仍然可以在UTC时间戳中看到那种“跳跃”。

从“用户空间”到“内核空间”(在抢占/系统调用期间),如果没有进行任何实质内核工作,将需要大约1000个CPU周期...

如果你的进程处于等待状态(通过调用一些阻塞IO),它甚至可能会变得更糟......

所以我真的没有得到你的“测试”。 IMO这是完全正常的。

答案 2 :(得分:0)

您可以发布代码以显示您如何生成此数据吗?并提供有关您正在运行此机器的详细信息?

使用以下内容,我得不到你得到的东西。

        for (int i = 0; i < 10; i++)
        {

            Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + " - " + DateTime.UtcNow.Ticks.ToString());

            Thread.Sleep(10);
        }

答案 3 :(得分:0)

Esteban是正确的,系统时钟更改会导致连续轮询之间的增量时间发生变化。 Windows时间服务是否每小时进行一次这些更改?可能在一小时内漂流一分钟?

要在您的计算机上发现这种情况,如果您跟踪检查之间的变化差异,您可以设置一个非常高的delta变化的条件断点。

long delta = 0;
long ticks = 0;
long lastTicks = DateTime.UtcNow.Ticks;
while (true)
{
    ticks = DateTime.UtcNow.Ticks;
    delta = ticks - lastTicks;
    lastTicks = ticks;
    // Conditional breakpoint: delta > 100000000 Is True
    Console.WriteLine("{0} - {1}", ticks, delta);
}

答案 4 :(得分:0)

原始输出在DebugView中捕获。我的托管应用程序正在进行p / invoke OutputDebugString调用,只是在一个也称为Thread.Sleep(1)的线程中从紧密循环输出DateTime.UtcNow.Ticks。

System information for \\JLECOURSXP:
Uptime:                    6 days 6 hours 22 minutes 53 seconds
Kernel version:            Microsoft Windows XP, Multiprocessor Free
Product type:              Professional
Product version:           5.1
Service pack:              3
Kernel build number:       2600
Registered organization:
Registered owner:          setup
Install date:              6/15/2007, 3:35:29 PM
IE version:                7.0000
System root:               C:\WINDOWS
Processors:                2
Processor speed:           2.9 GHz
Processor type:            Intel(R) Pentium(R) D CPU
Physical memory:           3070 MB
Video driver:              RADEON 9250 - Secondary