WPF線程模型

来源:https://www.cnblogs.com/leolion/p/18075937
-Advertisement-
Play Games

1. 渲染系統概述 WPF 採用保留模式渲染系統 (Retained Mode Rendering System),該系統可分為 UI 線程和複合線程兩個主要部分,兩者協作完成 WPF 應用程式的渲染工作。 1.1 立即模式GUI和保持模式GUI 圖形 API 可分為保留模式API 和即時模式API ...


1. 渲染系統概述

WPF 採用保留模式渲染系統 (Retained Mode Rendering System),該系統可分為 UI 線程和複合線程兩個主要部分,兩者協作完成 WPF 應用程式的渲染工作。

1.1 立即模式GUI和保持模式GUI

圖形 API 可分為保留模式API 和即時模式API。 Direct2D 是一種即時模式 API。 WPF 是保留模式 API 的一個示例。

1.1.1. 立即模式GUI

保留模式 API 是聲明性的。 應用程式從圖形基元(如形狀和線條)構造場景。 圖形庫將場景的模型存儲在記憶體中。 為了繪製幀,圖形庫將場景轉換為一組繪圖命令。 在幀之間,圖形庫將場景保留在記憶體中。 若要更改呈現的內容,應用程式會發出命令來更新場景,例如添加或刪除形狀。 然後,該庫負責重繪場景。

每渲染一幀時(很多機器都可以做到1秒鐘60幀),渲染庫需要執行渲染每個元素的指令,所以這種庫無需記住你已經渲染了什麼東西,反正每次都會全部重繪。會持續消耗你的CPU和GPU資源。

即時模式的GUI庫常用於更動態的元素表現,比如實時圖表,動畫,特效,游戲等,任何一個像素的改變,都會快速的呈現給你的用戶。

img

1.1.2. 保持模式GUI

即時模式 API 是過程性的。 每次繪製新幀時,應用程式都會直接發出繪圖命令。 圖形庫不會在幀之間存儲場景模型。 相反,應用程式會跟蹤場景。

由開發者調用渲染庫的API,適時的重繪需需要改變的元素。這就需要渲染庫有能力記住之前都渲染了什麼東西,所以也會占用更多的記憶體。

保留模式的GUI庫通常更容易使用,使開發更快,但它們也通常也會需要更多的開銷,比如要記住元素的位置、層級、遮蓋情況等等。

img

保留模式 API 可能更易於使用,因為 API 會為你執行更多工作,例如初始化、狀態維護和清理。 另一方面,它們通常不太靈活,因為 API 施加了自己的場景模型。 此外,保留模式 API 可能具有更高的記憶體要求,因為它需要提供通用場景模型。 使用即時模式 API,可以實現有針對性的優化。

2. 線程模型

2.1. 概述

WPF 應用程式有兩類線程負責渲染:一個用於管理 UI 叫 UI 線程,另一個用於處理渲染叫複合線程,也叫呈現線程。 當 UI 線程接收輸入、處理事件、繪製屏幕和運行應用程式代碼時,複合線程通過隱藏方式在後臺高效運行。

2.1.1. UI線程

UI 線程是 WPF 應用程式最重要的線程。它負責處理所有用戶交互事件,如按鈕單擊、菜單選擇以及鍵盤和滑鼠輸入。它還負責計算 UI 元素的佈局、處理數據綁定、觸發屬性更改等工作。UI 線程是單線程的,這意味著在同一時間只能有一個操作在 UI 線程上運行。

UI 線程在稱為 Dispatcher 的對象內對工作項進行排隊。 Dispatcher 基於優先順序選擇工作項,並運行每一個工作項直到完成。 每個 UI 線程必須具有至少一個 Dispatcher,且每個 Dispatcher 都可精確地在一個線程中執行工作項。

UI 線程也可以啟用多個,由於多線程程式既複雜又難以調試,因此當存在單線程解決方案時,應避免使用多線程程式。

UI 線程的主要職責是:

  1. 計算佈局和測量視覺(Visual)對象。
  2. 實現數據綁定和依賴屬性系統。
  3. 處理用戶輸入和事件。
  4. 安排和分派渲染工作項給複合線程。

總的來說,UI 線程的工作是計算最終結果,並安排複合線程執行渲染工作。

2.1.2. 複合線程

複合線程負責 WPF 視覺層次結構的實際渲染工作。當應用程式的 UI 需要在屏幕上重新繪製時,複合線程就會介入,包括視窗大小調整、動畫以及任何影響 UI 外觀的操作。

複合線程與 UI 線程緊密協作。UI 線程計算佈局並安排 Visual 對象,複合線程會渲染 Visual 對象,並將其發送給桌面視窗管理器以在屏幕上顯示。

複合線程是一個線程池,包含若幹個工作線程,線程數量通常與系統的 CPU 內核數量相同,可以在多個內核上並行工作,從而提高 WPF 應用程式 UI 操作的性能。

複合線程的主要職責是:

  1. 生成可視化樹中元素的點陣圖。
  2. 應用效果(如3D變換、混合模式等)。
  3. 合成最終的渲染內容發送給桌面視窗管理器。

2.2. UI線程和複合線程協作

UI 線程和複合線程是 WPF 渲染系統的兩個重要部分,它們相互協作完成渲染工作:

  1. UI線程負責計算佈局、測量元素大小、響應用戶交互等。
  2. UI線程通過 VisualTarget.Render 方法將渲染工作項分派給複合線程線程池。
  3. 複合線程中的工作線程並行執行渲染工作,生成點陣圖數據。
  4. 複合線程將最終的渲染結果提交給桌面視窗管理器顯示。

3. 性能優化

若要生成響應迅速、用戶友好的應用程式,訣竅在於通過保持工作項小型化來最大化 Dispatcher 吞吐量。 這樣一來,工作項就不會停滯在 Dispatcher 隊列中,因等待處理而過時。 輸入和響應間任何可察覺的延遲都會讓界面卡頓無響應,帶來糟糕體驗。

需要註意的是,UI線程不應該執行長時間的操作,否則會導致UI無響應。相反,應該在後臺線程上執行這些任務。

WPF 應用程式在處理大型操作時,如涉及大型計算,或需要查詢某些遠程伺服器上的資料庫。通常情況下,解決方法是在單獨的線程中處理大型操作,讓 UI 線程更多傾向於處理 Dispatcher 隊列中的工作項。大型操作完成後,再通過 Dispatcher 將結果發送到 UI 線程進行安全渲染。

總的來說,UI 線程專註於用戶交互和佈局,而複合線程專註於高效呈現 UI。通過正確地利用這兩個線程,可以構建響應靈敏且高效的 WPF 應用程式。

參考引用:

https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/advanced/threading-model?view=netframeworkdesktop-4.8&viewFallbackFrom=netdesktop-8.0

https://learn.microsoft.com/zh-cn/windows/win32/learnwin32/retained-mode-versus-immediate-mode

https://zhuanlan.zhihu.com/p/534695668


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在MyBatis中,如果你使用resultType而不是resultMap,並且結果集中有同名欄位,則預設情況下後出現的欄位值會覆蓋前面的欄位值。這是因為MyBatis在將結果集映射到Java對象時,是按照欄位名稱一一對應進行賦值的。 但若你希望更精確地控制映射關係,並且避免自動覆蓋行為,則可以用r ...
  • 當開發者意識到代碼庫開始變得般混亂不堪時,就會在現有項目中引入狀態機。狀態機的引入有助於將複雜多變的應用程式狀態轉換過程組織得更為有序和清晰,從而避免代碼陷入難以維護的境地。 ...
  • 優秀可靠的數倉體系,需要良好的數據分層結構。合理的分層,能夠使數據體系更加清晰,使複雜問題得以簡化。以下是該項目的分層規劃。 1 設計要點 (1)ODS層的表結構設計依托於從業務系統同步過來的數據結構 (2)ODS層要保存全部歷史數據,故其壓縮格式應選擇壓縮比較高的,此處選擇gzip (3)ODS層 ...
  • 全面介紹雲計算安全的意義、安全模型、雲安全挑戰、雲安全最佳實踐和技術解決方案,最終深入研究雲安全案例,讓大家對雲安全有全面的理解。 關註【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智能 ...
  • 我們在使用pandas處理完數據之後,最終總是要把數據作為一個文件保存下來,那麼,保存數據最常用的文件是什麼呢?我想大部分人一定會選擇csv或者excel。 剛接觸數據分析時,我也是這麼選擇的,不過,今天將介紹幾種不一樣的存儲數據的文件格式。這些文件格式各有自己的一些優點,希望本文能讓你以後的數據存 ...
  • 前言 想開發一些小工具,所以想系統性的學習一遍aardio,之前都是哪裡不會搜哪裡,順便寫些教程。我的主要語言是Python,所以會以Python作為對比來加深印象。 aardio的基礎語法和JavaScript基本類似,如果你學過JavaScript,aardio很容易上手。下麵的文檔來自官方文檔 ...
  • 源生成器是 C# 9 中引入的一項功能,允許在編譯過程中動態生成代碼。 它們直接與 C# 編譯器集成(Roslyn)併在編譯時運行,分析源代碼並根據分析結果生成附加代碼。 源生成器提供了一種簡化的自動化代碼生成方法,無需外部工具或單獨的預編譯步驟。 通過無縫集成到編譯過程中,源生成器可以提高生產力、 ...
  • 這是一個我個人寫的庫,主要實現的是基於tcpclient的網站外擴網盤的解決方案,可以使用家用網路外掛個人電腦中的資源到自己的網站上,已經上傳nuget,大家可以直接在nuget包管理中搜索到,直接搜索ZmjNetDisk即可,下麵介紹具體的使用方式: 另外一提這個庫做的比較的個人化,因為他就是為了 ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...