8

C# Thread.Sleep 不精准的问题以及解决方案

 2 years ago
source link: https://www.cnblogs.com/stulzq/p/16248993.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

C# Thread.Sleep 不精准的问题以及解决方案

最近在写一个熔断的 SDK,其中一种策略是根据慢请求来进行熔断。

我们在测试的时候,在对应 API 里面采用了 Thread.Sleep(ms) 来模拟慢请求。

设置的慢请求阈值是 RT 100ms,我们设置了 Thread.Sleep(90ms),但是发现竟然触发了熔断。最近分析发现是 Thread.Sleep 并不精准,在测试机器(Windows 10)上偏差最大超过了 10ms,在我自己的电脑上(Mac)偏差最大 5ms。

为什么会这样呢?“因为Thread.Sleep保证的是至少休眠指定的值”(来自时总的解答 https://www.cnblogs.com/InCerry)

这不是 C# 的问题,JAVA 也一样。

编写了 JAVA 代码,发现结果在我的机器上和 C# 是一样的,最大偏差 5ms。

这个偏差和机器CPU、负载、Sleep 时间、操作系统有关。

如何解决这个问题?我尝试降低 Sleep 时间,通过循环计时,发现这个方法的精准度挺高的。

static void Sleep(int ms)
{
    var sw = Stopwatch.StartNew();
    var sleepMs = ms - 16;
    if (sleepMs > 0)
    {
        Thread.Sleep(sleepMs);
    }
    while (sw.ElapsedMilliseconds < ms)
    {
        Thread.Sleep(0);
    }
}

经过了时总的优化

上面的代码运行测试:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK