我有一個代碼引擎通過播放使用waveOutOpen和waveOutWrite API方法相繼小塊播放很長的WAV文件。爲了在文件播放時更新我的UI,在每個緩衝區完成播放時從回調函數中調用一個單獨的線程(因爲您希望儘可能少地執行回調函數內部),該線程調用我的表單中的方法。Control.Invoke()與其委託的調用之間的延遲時間有多長?
的形式包含一個類層次EventHandler
用於處理在其內我用新信息更新UI元素的方法。在從waveOutWrite回調函數調用的形式方法,我使用Invoke方法,像這樣:
if (_updatedisplay == null)
{
// UpdateDisplay contains code to set control properties on the form
_updatedisplay = new EventHandler(UpdateDisplay);
}
Invoke(_updatedisplay);
萬物的工作,但現在看來,曾經在一段時間沒有在UI的更新明顯滯後或延遲元素。這很容易看出來,因爲我使用UpdateDisplay方法來驅動動畫,所以延遲顯示爲「跳躍」,其中精靈在跳轉到其預期位置之前似乎凍結一秒。
是否有可能,有時有涉及跨線程通信這樣的長(也許10-15毫秒)延遲?如果是這樣,處理這樣的事情的更好方法是什麼?
更新:順便說一下,我絕對不確保Invoke
是這裏的罪魁禍首。另一種可能性是當大量音頻播放結束和回調函數實際被調用時之間的延遲。
更新2:每itowlson
的建議下,我使用的System.Diagnostics.Stopwatch
到基準滯後Invoke
和方法調用之間。在1156次測量中,我在0ms得到1146次,在1ms得到8次,在2ms得到2次。我認爲可以肯定地說Invoke
並不是我的罪魁禍首。
我只是使用的BeginInvoke試過了,但它仍然是hiccuppy。此外,我也遇到了同樣的問題,回想起使用高分辨率定時器的回調來運行動畫,並得到了同樣的毛刺。我不知道這是用.Net用戶界面的基礎嗎? – MusiGenesis 2010-02-20 22:01:29
不,至少就Windows而言,它是*任何* UI的基礎。 Windows Forms中的消息體系結構並不新鮮,即使是C++應用程序也可以在Windows中運行。如果您嘗試更新進度條或者您不應該跨線程調用的東西。而是使用互鎖寫入到UI線程以特定間隔讀取的進度變量。 – Josh 2010-02-20 22:06:43
這聽起來像*也許*動畫組件在抽取信息方面並不是一個好公民,但我對這裏發生的事情感到猶豫不決,尤其是因爲您不確定Invoke是什麼問題。嘗試捕獲BeginInvoke被調用時和UpdateDisplay開始執行時的時間:這可能有助於確定跨線程調用是否確實是問題。 (你需要使用高分辨率的時間。) – itowlson 2010-02-20 22:44:14