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库常用于更动态的元素表现,比如实时图表,动画,特效,游戏等,任何一个像素的改变,都会快速的呈现给你的用户。

1.2.2. 保持模式GUI

即时模式 API 是过程性的。 每次绘制新帧时,应用程序都会直接发出绘图命令。 图形库不会在帧之间存储场景模型。 相反,应用程序会跟踪场景。
由开发者调用渲染库的API,适时的重绘需需要改变的元素。这就需要渲染库有能力记住之前都渲染了什么东西,所以也会占用更多的内存。
保留模式的GUI库通常更容易使用,使开发更快,但它们也通常也会需要更多的开销,比如要记住元素的位置、层级、遮盖情况等等。
保留模式 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 应用程序。
 
 

WPF线程模型的更多相关文章

  1. WPF 线程:使用调度程序构建反应速度更快的应用程序

    原文:WPF 线程:使用调度程序构建反应速度更快的应用程序 作者:Shawn Wildermuth 原文:http://msdn.microsoft.com/msdnmag/issues/07/10/ ...

  2. WPF QuickStart系列之线程模型(Thread Model)

    这篇博客将介绍WPF中的线程模型. 首先我们先来看一个例子,用来计算一定范围内的素数个数. XAML: <Grid> <Grid.RowDefinitions> <Row ...

  3. 编写高质量代码改善C#程序的157个建议——建议87:区分WPF和WinForm的线程模型

    建议87:区分WPF和WinForm的线程模型 WPF和WinForm窗体应用程序都有一个要求,那就是UI元素(如Button.TextBox等)必须由创建它的那个线程进行更新.WinForm在这方面 ...

  4. WPF的线程模型

    原文:WPF的线程模型 WPF的线程模型            周银辉 谈到多线程,很多人对其可能都不太有好感,觉得麻烦与易出错.所以我们不排除有这样的情况:假设我对“多线程”.“异步”这些字眼潜意识 ...

  5. 看我是如何处理自定义线程模型---java

    看过我之前文章的园友可能知道我是做游戏开发,我的很多思路和出发点是按照游戏思路来处理的,所以和web的话可能会有冲突,不相符合. 来说说为啥我要自定义线程模型呢? 按照我做的mmorpg或者mmoar ...

  6. HBase的Write Ahead Log (WAL) —— 整体架构、线程模型

    解决的问题 HBase的Write Ahead Log (WAL)提供了一种高并发.持久化的日志保存与回放机制.每一个业务数据的写入操作(PUT / DELETE)执行前,都会记账在WAL中. 如果出 ...

  7. Netty学习三:线程模型

    1 Proactor和Reactor Proactor和Reactor是两种经典的多路复用I/O模型,主要用于在高并发.高吞吐量的环境中进行I/O处理. I/O多路复用机制都依赖于一个事件分发器,事件 ...

  8. Mina、Netty、Twisted一起学(十):线程模型

    要想开发一个高性能的TCP服务器,熟悉所使用框架的线程模型非常重要.MINA.Netty.Twisted本身都是高性能的网络框架,如果再搭配上高效率的代码,才能实现一个高大上的服务器.但是如果不了解它 ...

  9. servlet的生命周期与运行时的线程模型

    第 14 章 生命周期 注意 讲一下servlet的生命周期与运行时的线程模型,对了解servlet的运行原理有所帮助,这样才能避免一些有冲突的设计. 如果你不满足以下任一条件,请继续阅读,否则请跳过 ...

  10. eventloop & actor模式 & Java线程模型演进 & Netty线程模型 总结

    eventloop的基本概念可以参考:http://www.ruanyifeng.com/blog/2013/10/event_loop.html Eventloop指的是独立于主线程的一条线程,专门 ...

随机推荐

  1. Mac 上 redis 的安装方法

    1.由于需要用到编译,所以先安装xcode,注意利用appstore安装xcode后,记得打开xcode 点install,也可以建立一个macos项目,运行下 试下. 2. 去官网下载:https: ...

  2. MyBatis动态sql之foreach标签 构建 in 语句

    <foreach> 元素主要用在构建 in 条件中,它可以在 SQL 语句中迭代一个集合.<foreach> 元素的属性主要有 item.index.collection.op ...

  3. SP277 CTGAME - City Game 题解

    题目传送门 前置知识 单调栈 解法 令 \(f_{i,j}(1 \le i \le n,1 \le j \le m)\) 表示从 \((1,j)\) 到 \((i,j)\) 中以 \((i,j)\) ...

  4. 从零开始的react入门教程(九),react context上下文详解,可能有点啰嗦,但很想让你懂

    壹 ❀ 引 我在从零开始的react入门教程(八),redux起源与基础用法一文中,介绍了redux的前辈Flux,以及redux关于单项数据更新的基本用法.我们在前文提到,相对Flux支持多个sto ...

  5. Google搜索操作符:让你秒变搜索专家

    搜索引擎对互联网的重要性不言而喻,不过,随着ChatGPT及其类似AI工具的推出,对搜索引擎带来了前所未有的挑战. 因为ChatGPT具有自然语言处理能力,能够更好地理解用户的搜索意图,提供更准确.更 ...

  6. 详解网络知识:iptables规则

    本文分享自华为云社区<[理解云容器网络]1-基础篇-iptables介绍>,作者: 可以交个朋友. iptables规则 下图为数据包到达linux主机网卡后,内核如何处理数据包的大致流程 ...

  7. powerdesigner自定义实体显示的属性

    我做概要设计的时候需要画实体的逻辑模型图,默认的时候是这样的: 但是我想只保留属性名,隐藏数据类型和下面的横线怎么办?效果如下: 按以下操作即可实现:

  8. RAID 10磁盘阵列实践

    RAID概述 RAID技术通过把多个硬盘设备组合成一个容量更大.安全性更好的磁盘阵列,利用分散读写技术来提升磁盘阵列整体的性能,同时把多个重要数据的副本同步到不同的物理硬盘设备上,从而起到了非常好的数 ...

  9. fastdfs存储和下载过程

  10. JAVA 考试管理系统 大作业(一):需求分析

    好家伙,有需要的拿去借鉴吧(虽然我也百度了很多) 题目如下: 题目四:考试管理系统 (选做要求:使用图形用户界面) 分3种用户角色:教务员(具有管理权限).教师.学生 l  教务员:可以进行用户管理( ...