我需要在特定的时间后执行一个函数,因此我使用此代码。
_start = DateTime.Now;
await Task.Delay(_app.Settings.AudioFileStartVarianz.BaseSpan).ContinueWith(x =>
{
Console.WriteLine(DateTime.Now - _start);
});
让我们说我想要等待0.04秒。我现在的问题是它的工作不够精确。在调用该函数5次后,我得到以下输出:
如果我使用此代码,它的工作方式会更好
_start = DateTime.Now;
Thread.Sleep(_app.Settings.AudioFileStartVarianz.BaseSpan);
Console.WriteLine(DateTime.Now - _start);
但是现在我遇到了问题,该函数没有异步运行,有什么不好因为我正在播放音频文件(NAudio)。
我有什么想法可以在这里等待异步,以便我的音频文件没有停止?
KR Manuel
答案 0 :(得分:3)
两次通话之间的差异Thread.Sleep
& Task.Delay
,Thread.Sleep
调用OS方法来休眠线程,Task.Delay
创建Timer
来模拟延迟。
电话有效......
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中的计时器出了名的低分辨率 - 大约15ms的错误。我认为因为这样你才能得到你的结果。
坏消息是,正如你所说,休眠线程不是异步的,所以为了获得异步,你需要接受定时器分辨率错误。我不认为有任何理智的方法可以避免它。
答案 1 :(得分:1)
要获得准确的计时器,您应该使用multimedia timer:
多媒体计时器服务允许应用程序安排计时器事件 具有最高分辨率(或精度)的硬件 平台。这些多媒体计时器服务允许您安排计时器 比其他计时器服务更高分辨率的事件。
你可以在那里找到一个实现:
http://www.codeproject.com/Articles/5501/The-Multimedia-Timer-for-the-NET-Framework
因此,对于您的示例,它可能类似于
编辑代码简化:
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");
}
请勿尝试使用DateTime检查计时器是否正确滴答。现在,精确度大约为15或16 ms,具体取决于系统。