.net thread.sleep不准确

时间:2016-01-06 22:45:14

标签: .net multithreading sleep

我疯了!! 我通过gsm和语音规范发送音频,我必须发送语音数据包,然后等待20毫秒才能获得正常的语音。我使用system.threading.thread.sleep(20)。但是,我注意到声音很慢。但是当我运行另一个不同的应用程序时,声音会正常。

经过一些调试后,我发现system.Threading.Thread.Sleep(20)需要31毫秒,但如果我运行另一个不同的应用程序,Thread.Sleep(20)将始终是准确的。

我可以使用哪些其他替代方案,以使线程准确地睡眠20毫秒&同时不影响PC的性能。

谢谢,

2 个答案:

答案 0 :(得分:2)

Sleep(20)表示至少睡眠20毫秒。基本上,它会挂起线程,并且不会恢复指定延迟的调度。之后,线程仍然必须安排实际恢复运行。取决于正在运行的其他线程可能会立即或稍后。这里没有保证。

documentation称之为:

  

系统时钟以称为时钟分辨率的特定速率滴答。   实际超时可能不完全是指定的超时,因为   指定的超时将调整为与时钟滴答一致。   有关时钟分辨率和等待时间的更多信息,请参阅   睡眠功能主题。此方法从中调用Sleep函数   Windows系统API。

答案 1 :(得分:1)

如前所述,准确的时间安排通常需要一个不会时间切片的线程/流程,为此,您必须Spin而不是Sleep

选项1

如果你想要绝对准确性,我会使用一个带秒表的专用高优先级线程。

bool running = true;
Thread t = new Thread(() =>
{
    Stopwatch sw = Stopwatch.StartNew();
    while (running)
    {
        if (sw.ElapsedMilliseconds >= 20)
        {
            RunCode();
            sw.Restart();
        }
    }
}) { Priority = ThreadPriority.Highest, IsBackground = true };

t.Start();

// ...

running = false;
t.Join();

选项2

稍微瘦下来,不会在不同的线程上运行但仍然会旋转。

while (true) 
{
    SpinWait.SpinUntil(() => false, TimeSpan.FromMilliseconds(20));
    RunCode();
}

选项3

一些开源高分辨率计时器代码。例如https://gist.github.com/HakanL/4669495