2011-06-13 102 views
6

從工作者線程調用UI線程討論了很多次,我們知道爲什麼要使用BeginInvoke()而不是Invoke()。我最近發佈了this question,在做了一些研究之後,我發現至少有三種不同的方式(在內部它們可能是相同的)在UI線程上調用(異步)某些東西。control.BeginInvoke()VS Dispatcher VS SynchronizationContext VS. - 可靠性

  1. Control.BeginInvoke()
  2. 使用SynchronizatoinContext
  3. 使用Dispatcher.BeginInvoke(priority..)

誰能告訴我這是一個可靠的方法來異步調用要在UI線程執行的方法。任何經驗?我看到Dispatcher.BeginInvoke具有優先組件,它是否更加可靠?

語境
我們使用someControl.BeginInvoke(),但注意到,有時候(可惜只有在最終用戶生產環境)的委託傳遞給BeginInvoke is永遠不會執行這讓我相信,它會創建到請求消息迷路。我們需要一種可靠的方式來回傳給UI線程。 control.Invoke()有時會掛起UI,因此我們不想去那裏。

+0

不要混淆WPF的WinForms。 – SLaks 2011-06-13 15:22:36

+0

我遇到了類似的問題......您是否有機會糾正這個問題? – 2011-11-23 22:44:42

+0

同樣在這裏,有沒有更新? – Pedro77 2013-06-17 17:28:03

回答

0

他們都按照他們應該的方式操作,如果您撥打BeginInvoke並且有時沒有任何反應,那麼環境或調用代碼中可能存在問題 - 可能並非BeginInvoke不可靠。那麼 - 可能有一個錯誤,但它可能性很小。

也許你可以給更多的上下文,我們可以幫助診斷。

+0

感謝您的迴應。我在我們的代碼中有類似的情況。 http://stackoverflow.com/questions/6270514/control-begininvoke-fails-to-call-the-delegate – karephul 2011-06-13 15:18:27

+0

嗨karephul,這很有趣,但在這種情況下沒有什麼幫助,因爲他們沒有找到答案。你在線程,進程,鎖等方面的基本設置是什麼? – 2011-06-13 15:27:49

+0

哦......是這個問題嗎?剛在這裏轉貼? – 2011-06-13 15:28:24

0

SynchronizationContext在更多情況下更具抽象性和適應性。它是具體實現的包裝。 MSDN說「同步模型的提供者可以擴展這個類併爲這些方法提供它們自己的實現」。

+0

SynchronizationContext優先於此處:http://social.msdn.microsoft.com/Forums/en-US/async/thread/1218c86e-fa9b-45a6-93b0-5e27616a6c21 – Steel 2012-12-13 05:22:09

0

你應該小心使用lambda函數和BeginInvoke。我有這樣的代碼導致了各種奇怪的行爲。

MyThing thing; 
while(GetThing(ref thing)) { 
    control.BeginInvoke((Action)(() => control.Text = thing.ToString())); 
} 

問題是,當您創建lambda函數時,不會評估thing。它在lamdba函數執行時進行評估。但它綁定到一個在生產者線程中同時發生變化的變量。

可以通過聲明的thing

MyThing thing; 
while(GetThing(ref thing)) { 
    MyThing thing_x = thing; 
    control.BeginInvoke((Action)(() => control.Text = thing_x.ToString())); 
} 

一個局部變量副本解決這個問題,或者你可以把醜陋的BeginInvoke在包裝

MyThing thing; 
while(GetThing(ref thing)) { 
    SetText(thing); 
} 

void SetText(MyThing thing) 
    control.BeginInvoke((Action)(() => control.Text = thing.ToString())); 
} 
相關問題