C# Thread.Sleep 不精準的問題以及解決方案

曉晨Master發表於2022-05-09

1.問題

最近在寫一個熔斷的 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 時間、作業系統有關。

2.解決

如何解決這個問題?我嘗試降低 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.Yield();
    }
}

經過了時總的優化

上面的程式碼執行測試:

相關文章