我的印象是,Thread.Sleep(x)
不精确,它所做的一切就是睡觉至少x
ms。见here,here和here。
当睡眠时间非常短时,例如1ms
,预计你会发现该线程偶尔会为15ms
睡觉。由于时钟中断率,这是apparently,默认情况下是每秒64
次。
几年前我试过这个,事实上,我也经历过15ms
分辨率。然而,我刚刚再次尝试,现在我看到1ms
到2ms
分辨率很少> 2ms。
发生了什么变化? .NET已经改变了(我现在正在使用4.6
,不记得我2年前使用过的东西)?也许是操作系统发生了变化? (我使用过,现在仍在使用AWS EC2 Windows Server,但可能还有更新。)
我的简单测试程序:
private static Stopwatch sw =new Stopwatch();
static void Main(string[] args)
{
var timer = new Stopwatch();
var results = new List<long>();
for (int i = 0; i < 100000; i++)
{
timer.Restart();
Thread.Sleep(1);
results.Add(timer.ElapsedMilliseconds);
}
foreach (var item in results.Where(x => x > 1).ToList())
{
Console.WriteLine(item );
}
Console.ReadLine();
}
Thread.Sleep
(以及kernel32中的底层Windows API Sleep
函数)的精度取决于系统时钟的分辨率,系统时钟的默认滴答速率约为15 ms。应用程序可以请求更高的分辨率,在这种情况下,全局使用最高请求的分辨率。
在这种情况下,您可能会看到低于15毫秒的分辨率,因为系统上运行的某些东西要求更高的分辨率。
如果您的应用程序实际上需要15毫秒以下的睡眠时间,它可以通过本机timeBeginPeriod函数请求更高的分辨率。
但是,请注意,底层计时器设备可能不支持您请求的分辨率,因此编写依赖于此行为的代码并不是一个好习惯,除非您完全确定将运行代码的硬件。