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
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 前言 本文介紹瞭如何使用三菱提供的MX Component插件實現對三菱PLC軟元件數據的讀寫,記錄了使用電腦模擬,模擬PLC,直至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1. PLC開發編程環境GX Works2,GX Works2下載鏈接 https:// ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • 1、jQuery介紹 jQuery是什麼 jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝 ...
  • 前言 之前的文章把js引擎(aardio封裝庫) 微軟開源的js引擎(ChakraCore))寫好了,這篇文章整點js代碼來測一下bug。測試網站:https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻譯js逆向(MD5加密,AES加密)附完整源碼 ...
  • 引言 現代的操作系統(Windows,Linux,Mac OS)等都可以同時打開多個軟體(任務),這些軟體在我們的感知上是同時運行的,例如我們可以一邊瀏覽網頁,一邊聽音樂。而CPU執行代碼同一時間只能執行一條,但即使我們的電腦是單核CPU也可以同時運行多個任務,如下圖所示,這是因為我們的 CPU 的 ...
  • 掌握使用Python進行文本英文統計的基本方法,並瞭解如何進一步優化和擴展這些方法,以應對更複雜的文本分析任務。 ...
  • 背景 Redis多數據源常見的場景: 分區數據處理:當數據量增長時,單個Redis實例可能無法處理所有的數據。通過使用多個Redis數據源,可以將數據分區存儲在不同的實例中,使得數據處理更加高效。 多租戶應用程式:對於多租戶應用程式,每個租戶可以擁有自己的Redis數據源,以確保數據隔離和安全性。 ...