C# Thread.Sleep 立即唤醒问题

6
我正在使用以下代码
Thread.Sleep(5);

在 while 循环结束时加入代码以尝试让每次迭代之间的延迟达到 5 毫秒。
有时它会睡眠 16 毫秒。我理解并接受这一点,因为它取决于 CPU 何时开始服务线程。不过,一旦它唤醒下一轮迭代,似乎在 sleep 调用之后立即醒来(我正在记录时间戳)。使用如此短的 sleep 时间间隔会被视为零,这是有问题的吗?

你能否发布调用Thread.Sleep()的代码? - Justin Niessner
别担心,只需发布时间戳记录代码。;] - bzlm
1
似乎5毫秒在误差范围之内,特别是使用时间戳时。请尝试使用StopWatch再次测试,并告诉我们是否仍然出现这种情况。 - Michael Meadows
4个回答

21
你遇到的问题是在大多数现代计算机上,DateTime.UtcNow 的分辨率约为10-15毫秒(尽管我看到文档说自NT 3.5以来大约是10毫秒)。如果你想要更高分辨率的计时,可以参考Stopwatch类,特别是Stopwatch.GetTimestamp()方法。
另外请注意,只有当高分辨率计时器可用时,Stopwatch才会使用它们(Stopwatch.IsHighResolution会在运行时告诉你)。如果不可用,它会退回到DateTime.UtcNow.Ticks。

4
很可能,问题仅仅是你的计时器具有有限的分辨率。如果它只更新,比如说,每10毫秒一次,即使过去了5毫秒,在某些迭代中你也会看到相同的时间戳。
你使用哪个计时器来生成时间戳?

1

如果我没记错的话,NT时间片是在NT内核中引入的,并且在XP中仍然以同样的方式活动,操作时间大约在5毫秒左右。我们正在构建一个实时应用程序,并遇到了这个问题。您将无法始终获得5毫秒的睡眠时间。我们发现有时会得到10-16毫秒,有时没有毫秒,偶尔很少得到5毫秒。

不过,我是在5年前进行这些测试的,所以自那以后可能已经发生了变化。


0
你在哪种系统上运行?时间间隔短可能取决于处理器及其支持的高分辨率。我曾在一个手持设备上运行过一款应用程序,其中计时器本身的分辨率为16ms。因此,这可能与硬件有关。尝试将时间周期增加到30ms,看看是否可以解决问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接