C# 任务延迟与线程睡眠解决精度
我需要在一段特定的时间后执行一个函数,因此我使用这段代码C# 任务延迟与线程睡眠解决精度,c#,multithreading,asynchronous,sleep,C#,Multithreading,Asynchronous,Sleep,我需要在一段特定的时间后执行一个函数,因此我使用这段代码 _start = DateTime.Now; await Task.Delay(_app.Settings.AudioFileStartVarianz.BaseSpan).ContinueWith(x => { Console.WriteLine(DateTime.Now - _start); }); 假设我想等待0.04秒。我现在的问题是它不够精确。调用函数5次后,我得
_start = DateTime.Now;
await Task.Delay(_app.Settings.AudioFileStartVarianz.BaseSpan).ContinueWith(x =>
{
Console.WriteLine(DateTime.Now - _start);
});
假设我想等待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);
- 00:00:00.0405879
- 00:00:00.0404284
- 00:00:00.0402117
- 00:00:00.0404908
- 00:00:00.0409088
KR Manuel两个调用
线程.Sleep
和任务.Delay
之间的区别在于线程.Sleep
调用操作系统方法来睡眠线程和任务。Delay
创建一个计时器来模拟延迟
这些电话有效地
private static extern int WaitOneNative(SafeHandle waitableSafeHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext);
……还有
promise.Timer = new Timer(state => ((DelayPromise)state).Complete(), promise, millisecondsDelay, Timeout.Infinite);
…分别
现在,windows中的计时器分辨率低是出了名的——大约有15毫秒的误差。我想正是因为这样,你才有了结果
坏消息是,正如您所说,休眠线程不是异步的,所以要获得异步,您需要接受计时器解析错误。我认为没有任何明智的方法可以避免它。要获得准确的计时器,您应该使用:
多媒体计时器服务允许应用程序安排计时器事件
以硬件可能的最大分辨率(或精度)
站台。这些多媒体定时器服务允许您安排定时器
事件的分辨率高于其他计时器服务
您可以在那里找到一个实现:
例如,它可以是
编辑代码简化:
Multimedia.Timer mmTimer = new Multimedia.Timer(new Container())
{
Mode = Multimedia.TimerMode.OneShot,
Period = 40,
Resolution = 1,
SynchronizingObject = this
};
mmTimer.Tick += new System.EventHandler(this.mmTimer_Tick);
startTime = DateTime.Now;
mmTimer.Start();
private void mmTimer_Tick(object sender, System.EventArgs e)
{
MessageBox.Show("ticks after 40ms");
}
不要试图检查计时器是否与日期时间正确同步。根据系统的不同,其精度大约为15或16毫秒
进一步阅读:不是Windows计时器将分辨率限制在15毫秒左右。相反,Windows计时器周围的.NET包装器施加了该限制。@JimMischel-我的理解是,该限制是操作系统的核心(设置为1/64秒或15.625秒),但可以更改。读一读。改变它的问题是功耗,因此便携式设备的电池寿命。是的,我读过。但至少在我使用过的每台台式机和笔记本电脑上,如果我创建一个1毫秒的计时器队列计时器,我会得到1毫秒。多媒体计时器已经被弃用十年了。不要使用它们。计时器队列计时器更灵活,使用更少的系统资源,并提供与多媒体计时器相同的精度。有关实现和示例,请参见。或者,使用线程池计时器。但是请关掉多媒体定时器。