如何确保Task.Delay更准确?
我有一个WPF应用程序,它广泛使用await
和async
方法。 有几个地方我叫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 (); }
- 使用Highlight.js在Jekyll Github页面中显示C#标签
- 在哪里写连接字符串? 在app.config或web.config中?
- 存储过程始终返回0
- 用自定义图像替换“new-row”的DataGridViewImageColumn中的“red-cross”
- EF 4.1 Code First:类型中的每个属性名称在查找表关联上必须是唯一错误
- 使用行选择将DataBase(.mdb / .accdb)导出到.csv
- Authorize和GetRoles在ASP.NET标识中不起作用
- 如何在.NET 4中使用Console.CancelKeyPress? (在.NET 3.5及更低版本中正常工作)
- 检查字符串是否为空或C#中的所有空格