程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> WPF學習筆記 - 2. Dispatcher

WPF學習筆記 - 2. Dispatcher

編輯:關於.NET

WPF 使用一個專用的 UI 線程來完成界面的操作和更新,這個線程會關聯一個唯一的 Dispatcher 對象,用於調度按優先順序排列的工作項隊列。Application.Run() 實際上就是對 Dispatcher.Run() 的間接調用。

Dispatcher 通過循環來處理工作項隊列,這個循環通常被成為 "幀 (DispatcherFrame)"。Dispatcher.Run() 創建並啟動這個幀,這也是 Application.Run() 啟動消息循環的最終途徑。

public sealed class Dispatcher
{
 [SecurityCritical, UIPermission(SecurityAction.LinkDemand, Unrestricted=true)]
 public static void Run()
 {
  PushFrame(new DispatcherFrame());
 }
}

DispatcherFrame 可以嵌套,並通過檢查 Continue 屬性來決定循環是否繼續。我們可以通過調用 Dispatcher.ExitAllFrames() 來終止所有的幀循環,當然這種編程方式並不可取,可能會造成一些意外出現。

與 Dispatcher 調度對象想對應的就是 DispatcherObject,在 WPF 中絕大部分控件都繼承自 DispatcherObject,甚至包括 Application。這些繼承自 DispatcherObject 的對象具有線程關聯特征,也就意味著只有創建這些對象實例,且包含了 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, RoutedEventArgs e)
{
 new Thread(() =>
 {
  this.Dispatcher.Invoke(DispatcherPriority.Normal,
   new Action(() => this.label1.Content = DateTime.Now.ToString()));
 }).Start();
}

如果在其他項目(比如類庫)中,我們可以用 Application.Current.Dispatcher.Invoke(...) 完成同樣的操作,它們都指向 UI Thread Dispatcher 這個唯一對象。

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,但當這類對象從修改狀態變成凍結狀態時,它即變成自由線程對象,不在具有線程關聯。(有關 Freezable 詳情可參考 MSDN)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved