首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 學習筆記:Dispatcher 執行緒模型 — UI 執行緒、跨執行緒存取與 Freezable

     編輯:關於.NET

Dispatcher 核心架構

WPF 採用單一 UI 執行緒模型,所有 UI 操作必須在建立控制項的執行緒 (UI 執行緒) 上進行。每個 UI 執行緒關聯唯一 Dispatcher 物件,負責依優先序調度工作項隊列。

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

Application.Run() 實為 Dispatcher.Run() 間接呼叫,啟動訊息迴圈 (DispatcherFrame)。DispatcherFrame 可巢狀,透過 Continue 屬性控制迴圈持續。Dispatcher.ExitAllFrames() 可終止所有框架 (不建議常規使用)。

DispatcherObject:執行緒親和性

WPF 絕大多數控制項繼承自 DispatcherObject (含 Application),具備**執行緒親和性**:只有擁有其 Dispatcher 的執行緒能直接存取。

跨執行緒存取異常

private void button1_Click(object sender, RoutedEventArgs e)
{
    new Thread(() => this.label1.Content = DateTime.Now.ToString()).Start();
}

跨執行緒存取異常

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();
}
  • DispatcherPriority.Normal:優先序等級
  • Action 委派:要在 UI 執行緒執行的程式碼

類庫專案可用 Application.Current.Dispatcher.Invoke(...),指向同一 UI 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();
}

BeginInvoke 將工作項排入隊列立即返回,背景執行緒繼續執行;UI 執行緒稍後依優先序處理。

Freezable:凍結後可跨執行緒存取

Freezable 間接繼承 DispatcherObject,但當從「可修改狀態」轉為「凍結狀態」 (Freeze()) 後,成為**自由執行緒物件**,失去執行緒親和性,可在任何執行緒安全存取。

  • 典型應用:Brush、Geometry、Transform、AnimationTimeline 等
  • 凍結後不可修改,效能更佳 (可跨執行緒共享)
  • 詳細請參考 MSDN Freezable 文件
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved