简体   繁体   English

Thread.Sleep的精度是否仍然很差?

[英]Is the precision of Thread.Sleep still poor?

I was under the impression that Thread.Sleep(x) is not precise and that all it will do is sleep the thread for at minimum x ms. 我的印象是Thread.Sleep(x) ,它所做的就是将线程休眠至少 x ms。 See here , here and here . 看到这里这里这里

When sleeping for a very low amount of time, eg 1ms , it is expected that you will find that the thread occasionally sleeps for about 15ms . 当睡眠时间非常短,例如1ms ,预计您会发现该线程偶尔会睡眠约15ms This is apparently due to clock interrupt rate which by default is 64 times per second. 显然是由于时钟中断率,默认情况下是每秒64次。

I tried this a couple of years ago and indeed, I too experienced the 15ms resolution. 几年前我试过这个,事实上,我也经历过15ms分辨率。 However, I have just tried again and now I am seeing 1ms to 2ms resolution with very rarely > 2ms. 但是,我刚刚再次尝试,现在我看到1ms2ms分辨率很少> 2ms。

What has changed? 发生了什么变化? Has .NET changed (I'm using 4.6 at the moment, don't remember what I used 2 years ago)? .NET已经改变了(我现在使用4.6 ,不记得2年前我用过的东西)? Perhaps it is the operating system which has changed? 也许是操作系统发生了变化? (I used and am still using AWS EC2 Windows Server, but perhaps there has been an update.) (我使用过,现在仍在使用AWS EC2 Windows Server,但可能还有更新。)

My simple test program: 我的简单测试程序:

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();

}

The precision of Thread.Sleep (and the underlying Windows API Sleep function in kernel32) is dependent on the resolution of the system clock, which has a default tick rate of roughly 15 ms . Thread.Sleep (以及kernel32中的底层Windows API Sleep函数)的精度取决于系统时钟的分辨率,系统时钟的默认滴答速率约为15 ms Applications can request a higher resolution, in which case the highest requested resolution is used globally . 应用程序可以请求更高的分辨率,在这种情况下,全局使用最高请求的分辨率

In this case case, you're likely seeing sub-15 ms resolution because something running on your system has requested a higher resolution. 在这种情况下,您可能会看到低于15毫秒的分辨率,因为系统上运行的某些东西要求更高的分辨率。

If your application actually needs sub-15 ms sleeps, it can request a higher resolution via the native timeBeginPeriod function. 如果您的应用程序实际上需要15毫秒以下的睡眠时间,它可以通过本机timeBeginPeriod函数请求更高的分辨率。

However, note that it is possible that the underlying timer device won't support your requested resolution, so it's not good practice to write code that relies on this behavior unless you're absolutely sure of the hardware your code will be running on. 但是,请注意,底层计时器设备可能不支持您请求的分辨率,因此编写依赖于此行为的代码并不是一种好习惯,除非您完全确定将运行代码的硬件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM