Точность Thread.Sleep все еще низка? - PullRequest
0 голосов
/ 31 августа 2018

У меня сложилось впечатление, что Thread.Sleep(x) не является точным, и все, что он будет делать, - это спать в потоке при минимальном x мс. См. здесь , здесь и здесь .

Когда спите в течение очень небольшого количества времени, например 1ms, ожидается, что вы обнаружите, что поток иногда спит около 15ms. Это , по-видимому, из-за частоты прерывания тактового сигнала, которая по умолчанию составляет 64 раз в секунду.

Я пробовал это пару лет назад, и действительно, я тоже испытал разрешение 15ms. Тем не менее, я только что попробовал еще раз, и теперь я вижу разрешение от 1ms до 2ms с очень редко> 2 мс.

Что изменилось? Изменился ли .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();

}

1 Ответ

0 голосов
/ 31 августа 2018

Точность Thread.Sleep (и базовая функция Windows API Sleep в kernel32) зависит от разрешения системных часов, , которое по умолчанию имеет частоту тиков примерно 15 мс . Приложения могут запрашивать более высокое разрешение, в этом случае самое высокое запрашиваемое разрешение используется во всем мире .

В этом случае вы, вероятно, видите разрешение менее 15 мс, поскольку что-то, работающее в вашей системе, запросило более высокое разрешение.

Если вашему приложению действительно требуется менее 15 мс сна, оно может запросить более высокое разрешение с помощью встроенной функции timeBeginPeriod .

Однако обратите внимание, что вполне возможно, что основное устройство таймера не будет поддерживать требуемое разрешение, поэтому не рекомендуется писать код, основанный на этом поведении, если вы не абсолютно уверены в том, какое оборудование будет работать с вашим кодом на.

...