WPF Dispatcher在界面操作中作用體現(xiàn)
對于一個開發(fā)人員來說,可能在開發(fā)一個程序的時候?qū)D形界面的要求并不是很高,因為他們不是美工。那么,使用了WPF后,開發(fā)人員可以輕松的實現(xiàn)精美的圖形界面。#t#
使用一個專用的 UI 線程來完成界面的操作和更新,這個線程會關聯(lián)一個***的WPF Dispatcher 對象,用于調(diào)度按優(yōu)先順序排列的工作項隊列。Application.Run() 實際上就是對 Dispatcher.Run() 的間接調(diào)用。
WPF Dispatcher通過循環(huán)來處理工作項隊列,這個循環(huán)通常被成為 "幀 (DispatcherFrame)"。Dispatcher.Run() 創(chuàng)建并啟動這個幀,這也是 Application.Run() 啟動消息循環(huán)的最終途徑。
- public sealed class Dispatcher
- {
- [SecurityCritical,
UIPermission(SecurityAction.
LinkDemand, Unrestricted=true)]- public static void Run()
- {
- PushFrame(new DispatcherFrame());
- }
- }
DispatcherFrame 可以嵌套,并通過檢查 Continue 屬性來決定循環(huán)是否繼續(xù)。我們可以通過調(diào)用 Dispatcher.ExitAllFrames() 來終止所有的幀循環(huán),當然這種編程方式并不可取,可能會造成一些意外出現(xiàn)。
與WPF Dispatcher調(diào)度對象想對應的就是 DispatcherObject,在 WPF 中絕大部分控件都繼承自 DispatcherObject,甚至包括 Application。這些繼承自 DispatcherObject 的對象具有線程關聯(lián)特征,也就意味著只有創(chuàng)建這些對象實例,且包含了 Dispatcher 的線程(通常指默認 UI 線程)才能直接對其進行更新操作。
當我們嘗試從一個非 UI 線程更新一個標簽,會看到一個如下的異常。
- private void button1_Click
(object sender, RoutedEventArgs e)- {
- new Thread(() => this.label1.
Content = DateTime.Now.
ToString()).Start();- }
按照 DispatcherObject 的限制原則,我們改用 Window.Dispatcher.Invoke() 即可順利完成這個更新操作。
- private void button1_Click
(object sender, Routed
EventArgs e)- {
- new Thread(() =>
- {
- this.Dispatcher.Invoke
(DispatcherPriority.Normal,- new Action(() => this.
label1.Content = DateTime.
Now.ToString()));- }).Start();
- }
如果在其他項目(比如類庫)中,我們可以用 Application.Current.Dispatcher.Invoke(...) 完成同樣的操作,它們都指向 UI Thread Dispatcher 這個***對象。
WPF Dispatcher還提供了 BeginInvoke 這個異步版本。
- private void button1_Click(object
sender, RoutedEventArgs e)- {
- new Thread(() =>
- {
- Application.Current.Dispatcher.
BeginInvoke(DispatcherPriority.Normal,- new Action(() =>
- {
- Thread.Sleep(3000);
- this.label1.Content =
DateTime.Now.ToString();- }));
- MessageBox.Show("Hi!");
- }).Start();
- }
凡事都有例外,WPF 還提供了一種繼承自 Freezable 的類型,盡管 Freezable 也間接繼承自 DispatcherObject,但當諸如WPF Dispatcher這類對象從修改狀態(tài)變成凍結(jié)狀態(tài)時,它即變成自由線程對象,不在具有線程關聯(lián)。