You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何循环调用Thread.Sleep(50ms)执行100次耗时超6秒而非预期的5秒?

为何循环调用Thread.Sleep(50ms)执行100次耗时超6秒而非预期的5秒?

这个问题我之前做性能测试时也踩过同款坑,其实核心就是两个因素叠加导致的正常现象——Thread.Sleep的精度远没有你想的那么“准”,再加上操作系统线程调度的额外开销,100次下来误差直接被放大到了1秒多。

我拆解开给你唠明白:

1. Thread.Sleep(50) 是“至少睡50ms”,不是“刚好睡50ms”

Windows系统的定时器有个基础分辨率,默认情况下大概是15.625ms(对应1/60秒,是早期兼容老系统留下的设定,Windows 11默认也没改这个)。当你调用Thread.Sleep(50)时,系统只会保证你的线程不会在50ms内被唤醒,但实际唤醒时间得等下一个系统定时器“滴答(tick)”到来的时候。

举个实际的例子:假设你调用Sleep时,距离下一个系统tick只剩2ms,那线程实际睡眠的时间就会是50ms + 13.6ms(凑到下一个tick的时间),直接多睡了10多毫秒。你看你的结果是6.2秒,100次下来每次平均多12ms,刚好和这个分辨率的误差完全对上。而且这个误差是每次循环都会有的,积少成多,5秒的基础时间就被拉到了6秒多。

2. 线程调度的额外“隐形开销”

就算Sleep刚好到点了,你的线程也不能立刻回到运行状态——它得先进入操作系统的“就绪队列”,等调度器选中它,才能继续执行下一次循环。

单次调度的开销可能只有几毫秒,但架不住100次叠加,这也会给总时间再添上一点“零碎成本”。

3. 这种精度误差完全是预期的

桌面级Windows(非实时系统)本来就不会给普通应用提供高精度定时,因为要平衡性能和功耗——如果一直用最高精度的定时器,CPU会被高频唤醒,笔记本的续航会直接跳水。

如果你真的需要更精准的定时(比如做时间敏感的测试),可以试试这两个小办法:

  • Stopwatch做“忙等待”:记录当前时间,循环检查是否到达目标时间,直到满足条件再继续(注意这个会占满CPU核心,别在生产环境用)。
  • 临时提高系统定时器分辨率:调用timeBeginPeriod(1)把精度拉到1ms(用完一定要调用timeEndPeriod(1)恢复默认),但这个会影响整个系统的功耗,只适合测试场景。

总结来说,你看到的6.2秒完全是正常情况,就是Sleep的精度误差+调度开销叠加的结果,不用觉得奇怪~

火山引擎 最新活动