2010-02-20 83 views
6

我有一個代碼引擎通過播放使用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並不是我的罪魁禍首。

回答

3

是的,有可能是一個任意長的延遲。通過向目標控件發送Windows消息來調用工程,因此只有在目標線程將消息泵送時纔會處理。如果線程正在處理消息,並且處理需要時間,那麼在線程抽取下一條消息之前可能會有明顯的延遲,從而處理調用。

一個更好的辦法可能是調用BeginInvoke。這並不能避免UI線程處理消息的潛在延遲,但它可以避免在等待UI線程抽取消息時阻止調用線程被阻塞。但是,這可能無助於你的場景,它聽起來像是UI線程的繁忙程度,導致動畫中出現問題。

更新響應您的更新:注意所有我想說的是,有可能任意長的延遲,不就是有是一個明顯的延遲或者說這是肯定的原因你的延遲。對於應用程序在消息處理中花費的時間來說,10-15ms看起來確實是一個非常長的時間,除非在UI線程中發生了一些非常密集的事情,所以您明智地考慮其他原因!

+0

我只是使用的BeginInvoke試過了,但它仍然是hiccuppy。此外,我也遇到了同樣的問題,回想起使用高分辨率定時器的回調來運行動畫,並得到了同樣的毛刺。我不知道這是用.Net用戶界面的基礎嗎? – MusiGenesis 2010-02-20 22:01:29

+2

不,至少就Windows而言,它是*任何* UI的基礎。 Windows Forms中的消息體系結構並不新鮮,即使是C++應用程序也可以在Windows中運行。如果您嘗試更新進度條或者您不應該跨線程調用的東西。而是使用互鎖寫入到UI線程以特定間隔讀取的進度變量。 – Josh 2010-02-20 22:06:43

+0

這聽起來像*也許*動畫組件在抽取信息方面並不是一個好公民,但我對這裏發生的事情感到猶豫不決,尤其是因爲您不確定Invoke是什麼問題。嘗試捕獲BeginInvoke被調用時和UpdateDisplay開始執行時的時間:這可能有助於確定跨線程調用是否確實是問題。 (你需要使用高分辨率的時間。) – itowlson 2010-02-20 22:44:14