2011-11-26 69 views
2

假設我有名稱爲「button1」的控制按鈕,名稱爲「doSomething」的功能。函數「doSomething」被另一個線程調用。應用程序調度員和控制調度員

我有兩種方法從UI線程調用函數doSomething。

首先,從控制按鈕調度

this.button1.Dispatcher.BeginInvoke(new Action(() => { doSomething(); })); 

;第二,從應用程序調度

this.Dispatcher.BeginInvoke(new Action(() => { doSomething(); })); 

結果是一樣的,什麼是真正的有什麼不同?

回答

3

相同的調度程序實例在同一個線程擁有的所有控件中被引用。沒有區別。

+0

你的意思是調度員是靜態的,由一個線程(UI線程)擁有? – brian

+0

@brian:靜態字段不是靜態的,靜態字段是靜態的,每個線程只有一個實例。應用程序引用UI-tread的調度程序。 –

+1

該功能是從他們的父母(窗口或控制)繼承和擁有的UI線程,我是吧? – brian

2

所有UI控件(它們都是正常創建的)共享同一個調度程序實例。該調度員正在使用UI線程。如果你在背景線程上創建了一些控件,它會在該線程上創建新的調度器,這不會很好。 在WinForms和WPF中避免大部分線程和UI控件問題的最好方法是使用System.Threading.SynchronizationContext.Current。工作流程很簡單:在UI線程中獲得System.Threading.SynchronizationContext.Current並將其保存在某處(例如在公共靜態字段中)。然後,只要您想在UI線程上運行一些代碼,就可以訪問該持久的SynchronizationContext實例並使用其SendPost方法。它會在線程上運行您的代理,其中SynchronizationContext已實現(用於UI線程上的當前情況)。此外,它足夠聰明,使用當前的調用方式(WinForms的消息循環和WPF的調度程序),並且如果您已經從UI線程調用,它將會同步運行您的委託。 請記住,只有當您在當前UI線程上創建第一個控件後,才應該獲得SynchronizationContext,因爲SynchronizationContext將在此之後初始化。

+0

單身調度員怎麼樣?我認爲調度器比SynchronizationContext簡單得多。 – brian

+0

當然,您可以將分派器保存爲單例。 Just SynchronizationContext在使用方面幾乎相同,並且您的代碼對於WinForms,Wpf和未來可能的框架將是統一的。 –

+0

簡單地使用Application.Current.Dispatcher.Invoke(...)來調用UI線程上的方法是不是可以? –