任务延迟与线程睡眠分辨率精度

Man*_*uth 3 c# multithreading sleep asynchronous

我需要在特定时间后执行一个函数,因此我使用此代码。

_start = DateTime.Now;
await Task.Delay(_app.Settings.AudioFileStartVarianz.BaseSpan).ContinueWith(x => 
        {
            Console.WriteLine(DateTime.Now - _start);

        });
Run Code Online (Sandbox Code Playgroud)

假设我想等待 0.04 秒。我现在的问题是它的工作不够精确。调用该函数 5 次后,我得到以下输出:

  • 00:00:00.0414220
  • 00:00:00.0536098
  • 00:00:00.0507841
  • 00:00:00.0467757
  • 00:00:00.0425790

如果我使用此代码,效果会更好

        _start = DateTime.Now;
        Thread.Sleep(_app.Settings.AudioFileStartVarianz.BaseSpan);
        Console.WriteLine(DateTime.Now - _start);
Run Code Online (Sandbox Code Playgroud)
  • 00:00:00.0405879
  • 00:00:00.0404284
  • 00:00:00.0402117
  • 00:00:00.0404908
  • 00:00:00.0409088

但是现在我遇到了问题,该功能没有异步运行,这有什么不好,因为我正在播放音频文件(NAudio)。

有什么想法可以在这里等待异步,这样我的音频文件就不会停止吗?

KR曼努埃尔

Eni*_*ity 5

两次调用之间的区别Thread.Sleep&Task.DelayThread.Sleep调用 OS 方法使线程休眠并Task.Delay创建一个Timer来模拟延迟。

这些电话有效...

private static extern int WaitOneNative(SafeHandle waitableSafeHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext);
Run Code Online (Sandbox Code Playgroud)

...和...

promise.Timer = new Timer(state => ((DelayPromise)state).Complete(), promise, millisecondsDelay, Timeout.Infinite);
Run Code Online (Sandbox Code Playgroud)

...分别。

现在 Windows 中的计时器分辨率低是出了名的 - 有 15 毫秒左右的错误。我认为正是因为这一点,你才能得到你的结果。

坏消息是,正如您所说,休眠线程不是异步的,因此要获得异步,您需要接受计时器解析错误。我不认为你有任何理智的方法可以避免它。