Control.Invoke()与其Delegate调用之间的延迟有多长?
我有一个代码引擎,通过使用waveOutOpen和waveOutWrite API方法连续播放较小的块来播放长WAV文件。 为了在文件播放时更新我的UI,在每个缓冲区完成播放时从回调函数更新我调用一个单独的线程(因为你想在回调函数中做尽可能少的事情)调用我的表单中的方法。
该表单包含一个类级别的EventHandler
,它处理一个方法,在该方法中我用新信息更新UI元素。 在从waveOutWrite回调函数调用的form方法中,我使用Invoke方法,如下所示:
if (_updatedisplay == null) { // UpdateDisplay contains code to set control properties on the form _updatedisplay = new EventHandler(UpdateDisplay); } Invoke(_updatedisplay);
Everythings工作,但似乎偶尔会有更新UI元素的明显延迟或延迟。 这很容易看到,因为我使用UpdateDisplay方法来驱动动画,因此延迟显示为“打嗝”,其中精灵在跳转到其预期位置之前会在一瞬间冻结。
这样的跨线程通信有时可能会有很长(可能是10-15毫秒)的延迟吗? 如果是这样,处理这样的事情的更好方法是什么?
更新 :顺便说一下,我绝对不确定Invoke
是否是罪魁祸首。 另一种可能性是在一大块音频完成播放和实际调用回调函数之间存在滞后。
更新2 :根据itowlson
的建议,我使用System.Diagnostics.Stopwatch
来测试Invoke
和方法调用之间的延迟。 在1156次测量中,我在0ms获得1146,在1ms获得8,在2ms获得2。 我认为说Invoke
不是我的罪魁祸首是安全的。
是的,可能会有任意长的延迟。 调用通过向目标控件发送Windows消息来工作,因此只有在目标线程泵送消息时才会对其进行处理。 如果线程已经在处理消息,并且该处理需要时间,则在线程泵送其下一个消息之前可能存在明显的延迟,从而处理Invoke。
更好的方法是调用BeginInvoke。 这并不能避免处理消息的UI线程中的潜在延迟,但它会在等待UI线程抽取消息时保存您的调用线程。 但是,这可能对您的场景没有帮助,因为它听起来像UI线程的忙碌导致动画中出现故障。
更新以响应您的更新:请注意我在这里说的是, 可能会有任意长的延迟,而不是会有明显的延迟,或者这肯定是您延迟的原因。 对于应用程序花费在消息处理上的10-15ms看起来似乎是非常长的时间,除非在UI线程上发生了一些非常密集的事情,所以考虑其他原因你当然是明智的!