如何确保Task.Delay更准确?

我有一个WPF应用程序,它广泛使用awaitasync方法。 有几个地方我叫await Task.Delay(...); 插入暂停。 但是我遇到的麻烦是虽然很多这些停顿都可以稍微偏离,但有些地方我绝对需要暂停才能准确。 换句话说,如果我调用await Task.Delay(2000); 在我的应用程序中有一些地方我需要保证它只会暂停2秒(而不是2.2秒)。

我相信问题来自于我确实有很多不同的异步方法,所以当我告诉其中一个延迟时,线程池中没有足够的线程,当它应该恢复活着时,结果,无意中,延迟比预期的更长。

当您的业务需要尽可能准确地延迟时,线程的C#“最佳实践”是什么? 很明显,异步方法似乎并不足够(即使它们很好阅读)。 我应该手动创建具有更高优先级的线程并使用Thread.Sleep吗? 我是否增加了线程池中的线程数? 我使用BackgroundWorker吗?

您无法真正使Task.Delay本身更准确,因为它基于内部Threading.Timer ,其分辨率最高可达15毫秒,并且调度回调到线程池需要花费时间。

如果你真的需要准确,你需要一个专门的线程。 你可以使用Thread.Sleep让它睡2秒钟,当它醒来时你可以做你需要做的事情。

由于Thread.Sleep导致上下文切换,其中线程离开CPU,更准确的选择是执行“忙等待” (例如,使用while循环)。 这将消除上下文切换回CPU的成本,这需要一些时间。

您应该意识到这些选项需要太多资源,您应该考虑这是否真的有必要。

  public static async void ExecuteWithDelay( this Action action, int delay ) { //await Task.Delay(delay); Action a = () => { new System.Threading.ManualResetEventSlim(false).Wait(delay); }; await Task.Factory.StartNew(a); action?.Invoke (); }