当前位置: 首页 > news >正文

【WPF.NET开发】优化性能:对象行为

本文内容

  1. 不删除对象的事件处理程序可能会使对象保持活动状态
  2. 依赖属性和对象
  3. Freezable 对象
  4. 用户界面虚拟化

了解 WPF 对象的内部行为有助于在功能和性能之间做出适当的取舍。

1、不删除对象的事件处理程序可能会使对象保持活动状态

对象传递给其事件的委托是对该对象的有效引用。 因此, 事件处理程序可以使对象保持活动状态的时间超过预期时间。 当对已注册为侦听对象事件的对象执行清理时,在释放对象前删除委托是非常必要的。 将不需要的对象保持为活动状态会增加应用程序的内存使用量。 在对象为逻辑树或可视化树的根时更是如此。

WPF 为事件引入了弱事件侦听器模式,在很难跟踪源和侦听器之间的对象生存期关系时,这种模式特别有用。 某些现有 WPF 事件使用此模式。 如果要实现具有自定义事件的对象,此模式可能会有用。 

有若干工具(如 CLR 探查器和工作集查看器)可以提供有关指定进程的内存使用量的信息。 CLR 探查器包括分配配置文件的许多非常有用的视图,其中包括已分配类型的直方图、分配和调用关系图、显示各代垃圾回收及上述回收之后托管堆的生成状态的时间线,以及显示每个方法分配和程序集加载的调用树。 

2、依赖属性和对象

通常,访问 DependencyObject 的依赖属性的速度不会慢于访问 CLR 属性的速度。 虽然设置属性值会产生一些小的性能开销,但是获取值与从 CLR 属性获取值的速度一样快。 抵销一些小的性能开销是因为依赖属性支持可靠的功能,如数据绑定、动画、继承和样式设置。 

DependencyProperty 优化

在应用程序中定义依赖属性时请务必谨慎。 如果 DependencyProperty 仅影响呈现类型元数据选项,而不影响其他元数据选项(如 AffectsMeasure),则应通替代其元数据来对其进行同样的标记。 

如果并非所有属性更改都会影响测量、排列和呈现,则通过属性更改处理程序手动使测量、排列和呈现阶段无效的做法可能会更高效。 例如,你可能决定仅在值大于设置限制时才重新呈现背景。 在这种情况下,值超过设置限制时,属性更改处理程序仅会使呈现无效。

将 DependencyProperty 设置为可继承会影响性能

默认情况下,注册的依赖属性是不可继承的。 但可以显式地将所有属性设置为可继承。 尽管这是一个有用的功能,但是将属性转换为可继承会影响性能,因为会增加属性无效的时长。

谨慎使用 RegisterClassHandler

调用 RegisterClassHandler 会允许保存实例状态,但请注意,每个实例上都会调用处理程序,这将导致性能问题。 应用程序要求保存实例状态时,仅使用 RegisterClassHandler。

在注册过程中为 DependencyProperty 设置默认值

创建要求默认值的 DependencyProperty 时,请将传递的默认元数据用作 DependencyProperty 的 Register 方法的参数来设置此值。 请使用此技术,而不要在构造函数中或在元素的每个实例上设置属性值。

使用 Register 设置 PropertyMetadata 值

创建 DependencyProperty 时,可以选择使用 Register 或 OverrideMetadata 方法设置 PropertyMetadata。 尽管对象可能有一个静态构造函数来调用 OverrideMetadata,但这不是最佳方案,并且会影响性能。 为了获得最佳性能,建议在调用过程中将 PropertyMetadata 设置为 Register。

3、Freezable 对象

Freezable 是一种特殊类型的对象,具有两种状态:解冻和冻结。 尽可能冻结对象会改进应用程序性能,并缩小其工作集。 

每个 Freezable 都有一个 Changed 事件,只要发生更改就会引发该事件。 不过,更改通知会降低应用程序的性能。

考虑以下示例,其中每个 Rectangle 使用相同的 Brush 对象:

rectangle_1.Fill = myBrush;
rectangle_2.Fill = myBrush;
rectangle_3.Fill = myBrush;
// ...
rectangle_10.Fill = myBrush;

默认情况下,WPF 为 SolidColorBrush 对象的 Changed 事件提供事件处理程序,以便使 Rectangle 对象的 Fill 属性无效。 在这种情况下,每当 SolidColorBrush 不得不引发其 Changed 事件时,必须为每个 Rectangle 调用回叫函数,这些回叫函数调用的累积将导致性能严重下降。 此外,此时添加和删除处理程序将会严重影响性能,这是因为应用程序将不得不遍历整个列表才能执行此操作。 如果应用程序方案从未更改 SolidColorBrush,你将为不必要地维护 Changed 事件处理程序付出代价。

冻结 Freezable 会改进其性能,因为不再需要因维护更改通知而消耗资源。 下表显示简单的 SolidColorBrush 在其 IsFrozen 属性设置为 true 时的大小,并列出该属性未设置为该值时的情况以供对比。 这假设将一个画笔应用于十个 Rectangle 对象的 Fill 属性。

State大小
已冻结的 SolidColorBrush212 字节
非冻结的 SolidColorBrush972 字节

以下代码示例演示了此概念:

Brush frozenBrush = new SolidColorBrush(Colors.Blue);
frozenBrush.Freeze();
Brush nonFrozenBrush = new SolidColorBrush(Colors.Blue);for (int i = 0; i < 10; i++)
{// Create a Rectangle using a non-frozed Brush.Rectangle rectangleNonFrozen = new Rectangle();rectangleNonFrozen.Fill = nonFrozenBrush;// Create a Rectangle using a frozed Brush.Rectangle rectangleFrozen = new Rectangle();rectangleFrozen.Fill = frozenBrush;
}

解冻的可冻结对象的已更改处理程序可以使对象保持活动状态

对象传递给 Freezable 对象的 Changed 事件的委托是对该对象的有效引用。 因此,Changed 事件处理程序可以使对象保持活动状态的时间超过预期时间。 当对已注册为侦听 Freezable 对象的 Changed 事件的对象执行清理时,在释放对象前删除委托是非常必要的。

WPF 还会在内部挂钩 Changed 事件。 例如,所有值为 Freezable 的依赖属性将自动侦听 Changed 事件。 采用 Brush 的 Fill 属性说明了此概念。

Brush myBrush = new SolidColorBrush(Colors.Red);
Rectangle myRectangle = new Rectangle();
myRectangle.Fill = myBrush;

将 myBrush 赋值给 myRectangle.Fill 时,指向回 Rectangle 对象的委托将添加到 SolidColorBrush 对象的 Changed 事件。 这意味着以下代码实际上不会使 myRect 可以进行垃圾回收:

myRectangle = null;

在这种情况下,myBrush 仍会使 myRectangle 保持活动状态,并在其引发 Changed 事件时对其进行调用。 请注意,将 myBrush 赋值给新 Rectangle 的 Fill 属性时,仅将另一个事件处理程序添加到 myBrush

清理这些类型的对象的建议方式是从 Fill 属性删除 Brush,这将进而删除 Changed 事件处理程序。

myRectangle.Fill = null;
myRectangle = null;

4用户界面虚拟化

WPF 还提供 StackPanel 元素的一个变体,用于自动“虚拟化”数据绑定子级内容。 在此上下文中,“虚拟化”一词指的是以下技术:通过此技术,从较多的数据项中生成一个对象子集,具体取决于屏幕上哪些项可见。 如果在指定时刻只有少量 UI 元素位于屏幕上,则此时生成大量 UI 元素需要占用大量内存和处理器。 VirtualizingStackPanel(通过 VirtualizingPanel 提供的功能)计算可见项,并与来自 ItemsControl(如 ListBox 或 ListView)的 ItemContainerGenerator 配合使用,以便仅为可见项创建元素。

作为性能优化的结果,将仅生成这些项的视觉对象,或如果它们在屏幕上是可见的,则保持活动状态。 这些视觉对象不再位于控件的可视区域时,则可能已被删除。 请勿将此与数据虚拟化发生混淆,数据虚拟化中的数据对象不会全部出现在本地集合中 - 而是根据需要进行流式处理。

下表显示了将 5000 个 TextBlock 元素添加到 StackPanel 和 VirtualizingStackPanel 并使其呈现所需的运行时间。 在此情形中,测量值是指从将文本字符串附加到 ItemsControl 对象的 ItemsSource 属性至面板元素显示此文本字符串之间的时间。

主机面板呈现时间 (ms)
StackPanel3210
VirtualizingStackPanel46

相关文章:

【WPF.NET开发】优化性能:对象行为

本文内容 不删除对象的事件处理程序可能会使对象保持活动状态依赖属性和对象Freezable 对象用户界面虚拟化 了解 WPF 对象的内部行为有助于在功能和性能之间做出适当的取舍。 1、不删除对象的事件处理程序可能会使对象保持活动状态 对象传递给其事件的委托是对该对象的有效…...

uniapp中封装一个svg转base64的组件

uniapp中由于不支持svg--》base64&#xff0c;同时无法使用h5中atob&#xff0c;这里我们采用js-base64插件实现这样一个组件&#xff0c;只要传人svg的代码即可在uniapp中转为base64&#xff0c;同时支持自定义参数&#xff0c;比如宽度&#xff0c;高度,等 1 安装 npm inst…...

QT播放gstreamer命令(三)---使用QMediaPlayer

前文&#xff1a; 因为之前听说过&#xff0c;QMediaPlayer已经集成了gstreamer&#xff0c;但是并没有什么接口来例子来说明&#xff0c;根本看不出来有任何gstreamer的形式&#xff0c;于是在QT5助手里面搜了一下&#xff0c;发现确实有gstreamer的痕迹&#xff0c;但是例子写…...

Ubuntu22扩大分区

一台Ubuntu一直以为扩展成功了的&#xff0c;但是用起来空间不够&#xff0c;才发现空间还是那么小&#xff0c;所以赶快想办法扩展。 首先尝试使用gparted软件&#xff0c;结果在软件里面发现硬盘分区/dev/sda3已经全分配78G了。 但是看df -H&#xff0c;明明没有扩展: /dev…...

数据结构篇-05:哈希表解决字母异位词分组

本文对应力扣高频100 ——49、字母异位词分组 哈希表最大的特点就是它可以把搜索元素的时间复杂度降到O(1)。这一题就是要我们找到 “字母异位词” 并把它们放在一起。 “字母异位词”就是同一个单词中字母的不同组合形式。判断“字母异位词”有两个视角&#xff1a;1、所含字…...

添加了gateway之后远程调用失败

前端提示500&#xff0c;后端提示[400 ] during [GET] to [http://userservice/user/1] 原因是这个&#xff0c;因为在请求地址写了两个参数&#xff0c;实际上只传了一个参数 解决方案&#xff1a;加上(required false)并重启所有相关服务...

C#,哥伦布数(Golomb Number)的算法与源代码

1 哥伦布数&#xff08;Golomb Number&#xff09; 哥伦布数&#xff08;Golomb Number&#xff09;是一个自然数的非减量序列&#xff0c;使得n在序列中正好出现G&#xff08;n&#xff09;次。前几个15的G&#xff08;n&#xff09;值为&#xff1a;1 2 2 3 3 4 4 4 5 5 5 6…...

JVM学习

1.Java虚拟机内部有哪些线程共享&#xff0c;那些线程隔离 程序计数器&#xff1a; 通过改变这个计数器的值来选取下一条需要执行的字节码命令 Java虚拟机栈&#xff1a; 栈&#xff0c;每个方法被执行时&#xff0c;Java虚拟机都会同步的创建一个栈帧用于存储局部变量表&…...

Visual Studio 20XX中utf-8中文在控制台显示乱码

文章目录 在 Visual Studio 20xx中&#xff0c;如果源码文件是 UTF8编码&#xff0c;要打印中文到控制台时&#xff0c;控制台会显示乱码&#xff0c;可以进行以下设置。 包含<Windows.h>头文件。在main函数初始调用SetConsoleOutputCP(CP_UTF8)设置控制台输出字符集为UT…...

拥抱个人成长与社会进步:自我认知与开放心态的相互影响

拥抱个人成长与社会进步&#xff1a;自我认知与开放心态的相互影响 Embracing Personal Growth and Societal Progress: The Interplay of Self-Awareness and Open-mindedness 一、引言 I. Introduction 在当今急速发展的时代&#xff0c;个人成长与社会进步交织在一起&…...

【PostgreSQL内核学习(二十五) —— (DBMS存储空间管理)】

DBMS存储空间管理 概述块&#xff08;或页面&#xff09;PageHeaderData 结构体HeapTupleHeaderData 结构 表空间表空间的作用&#xff1a;表空间和数据库关系表空间执行案例 补充 —— 模式&#xff08;Schema&#xff09; 声明&#xff1a;本文的部分内容参考了他人的文章。在…...

2024年 复习 HTML5+CSS3+移动web 笔记 之CSS遍 第5天

第 五 天 整个网站例 5.1 准备工作 项目目录与版心 base.css 5.2 网页制作思路 5.3 header 区域-整体布局 5.4 header区域-logo 5.5 header区域-导航 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&l…...

SpringBoot使用Kafka详解含完整代码

1. 前言 随着大数据和实时处理需求的增长&#xff0c;Kafka作为一种分布式流处理平台&#xff0c;与Spring Boot的集成变得尤为重要。本文将详细探讨如何在Spring Boot应用程序中设置和使用Kafka&#xff0c;从基础概念到高级特性&#xff0c;通过实际代码示例帮助读者深入理解…...

解决:java -jar 在cmd中运行 程序卡顿,卡死的 问题。BIO和NIO案例保存

解决 怎么解决&#xff0c;就是 日志别输出到 cmd 就行了。就行了。就行了。 java -jar demo.jar > output.log 2>&1 &最近写东西&#xff0c;遇到了 程序偶尔卡死的情况。是java -jar 启动的。具体卡死为&#xff1a;http请求超级卡顿 或 偶尔反应好多个请求&…...

LeetCode第824题 - 山羊拉丁文

题目 解答 String toGoatLatin(String S) {if (S null) {return "";}S S.trim();if (S.isEmpty()) {return "";}StringBuilder sb new StringBuilder();String[] tokens S.split(" ");for (int i 0, j 1, length tokens.length; i <…...

[Python] 什么是逻辑回归模型?使用scikit-learn中的LogisticRegression来解决乳腺癌数据集上的二分类问题

什么是线性回归和逻辑回归&#xff1f; 线性回归是一种用于解决回归问题的统计模型。它通过建立自变量&#xff08;或特征&#xff09;与因变量之间的线性关系来预测连续数值的输出。线性回归的目标是找到一条直线&#xff08;或超平面&#xff09;&#xff0c;使得预测值与观…...

那些不输于乙游男主人设的国漫男主

最近乙游的势头越来越猛&#xff0c;新宠旧爱一起上阵&#xff0c;叫人应接不暇。在二次元的世界里&#xff0c;乙游男主们凭借着超凡的魅力&#xff0c;成为了无数少女心中的理想对象。他们或冷酷、或温柔、或阳光、或神秘&#xff0c;每一个角色都有着独特的性格和故事。 乙游…...

Apache Doris 整合 FLINK CDC + Iceberg 构建实时湖仓一体的联邦查询

1概况 本文展示如何使用 Flink CDC Iceberg Doris 构建实时湖仓一体的联邦查询分析&#xff0c;Doris 1.1版本提供了Iceberg的支持&#xff0c;本文主要展示Doris和Iceberg怎么使用&#xff0c;大家按照步骤可以一步步完成。完整体验整个搭建操作的过程。 2系统架构 我们整…...

关于华为应用市场上架,申请权限未告知目的被驳回问题的简单处理方式

关于华为应用市场上架过程中出现的【您的应用在运行时&#xff0c;未同步告知权限申请的使用目的&#xff0c;向用户索取&#xff08;存储、拍照&#xff09;等权限&#xff0c;不符合华为应用市场审核标准。】 使用方式&#xff1a; 1、引入 import permision from "/m…...

【ElasticSearch】概述

文章目录 ElasticSearch1.基本介绍2.设计理念3.基本架构与核心概念学习参考资料&#xff1a; ElasticSearch 简单整理ES基本概念&#xff0c;设计理念&#xff0c;构建与使用&#xff0c;供回顾。 1.基本介绍 Elasticsearch 是一个基于 Apache Lucene 的开源的分布式搜索引擎…...

一人公司小龙虾真能月入过万?揭开OpenClaw速成班背后的智商税与PanelAI真实落地路径

最近“一人公司”四个字在全网刷屏&#xff0c;尤其是小龙虾&#xff08;OpenClaw及各类国产智能体&#xff09;出来后&#xff0c;仿佛每个人养一只就能躺着赚钱。两天三夜速成班、保就业协议、月入几万的截图……视频刷得越多&#xff0c;我越觉得韭菜太多&#xff0c;骗子都…...

WebMVC 和 WebFlux 架构选型

在 Java Web 开发领域&#xff0c;并发模型的演进是一个不断追求更高吞吐与更简单编程模型的过程。从早期 Servlet 的“一请求一线程”&#xff0c;到 Servlet 3.1 的异步非阻塞&#xff0c;再到 WebFlux 的响应式编程&#xff0c;每一次变革都提升了并发能力&#xff0c;却也增…...

浏览器自动化之王:OpenClaw+Qwen3.5-9B实现复杂表单填充

浏览器自动化之王&#xff1a;OpenClawQwen3.5-9B实现复杂表单填充 1. 为什么需要智能表单填充 在日常工作中&#xff0c;我们经常需要处理各种复杂的在线表单。从税务申报到签证预约&#xff0c;这些表单往往包含数十个字段&#xff0c;字段之间存在复杂的逻辑关系。传统自动…...

GNOME-BOXES虚拟机快速上手:从安装到共享文件全攻略

1. GNOME-BOXES初体验&#xff1a;为什么选择它&#xff1f; 第一次接触GNOME-BOXES是在我需要临时运行一个Windows应用的时候。作为一个长期使用Linux的用户&#xff0c;我一直在寻找一个既轻量又简单的虚拟机方案。试过VirtualBox&#xff0c;也用过VMware&#xff0c;但要么…...

​从散户到 “跟庄” | 职业交易者的聪明金钱心法 :看结构、抓流动性,提高胜率!​

从散户到 “跟庄” | 职业交易者的聪明金钱心法 :看结构、抓流动性,提高胜率! 聪明金钱概念是交易中能帮你建立巨大盈利优势的核心逻辑——它能让你看透价格走势的本质,精准找到高盈亏比入场点,而不是被表面波动牵着走。 今天就把聪明金钱的核心逻辑、实战方法和交易设置…...

CTF隐写术入门:从图片LSB到音频频谱的5种实战技巧

CTF隐写术实战指南&#xff1a;从图片LSB到音频频谱的5种核心技巧 第一次参加CTF比赛时&#xff0c;我盯着那道图片隐写题整整两小时毫无头绪——直到偶然用Stegsolve点开Alpha通道&#xff0c;flag赫然出现在眼前。这种"啊哈时刻"正是隐写术的魅力所在。不同于密码…...

从数据采集到回放验证:ADTF 适配 ROS 的 ADAS 测试实践婆

一、简化查询 1. 先看一下查询的例子 /// /// 账户获取服务 /// /// /// public class AccountGetService(AccountTable table, IShadowBuilder builder) {private readonly SqlSource _source new(builder.DataSource);private readonly IParamQuery _accountQuery build…...

从5V电源到485通信:一个工业级PT100温度变送器的全链路DIY搭建实录

从5V电源到485通信&#xff1a;一个工业级PT100温度变送器的全链路DIY搭建实录 在工业自动化领域&#xff0c;温度监测的可靠性和精度往往直接关系到生产安全与质量控制。传统温度变送器虽然成熟稳定&#xff0c;但对于需要定制化功能或特殊安装环境的场景&#xff0c;自主搭建…...

CogVideoX-2b实战落地:中小企业低成本视频制作新路径

CogVideoX-2b实战落地&#xff1a;中小企业低成本视频制作新路径 1. 引言&#xff1a;视频制作的门槛&#xff0c;真的降下来了吗&#xff1f; 对于很多中小企业的市场、运营或内容团队来说&#xff0c;制作一个高质量的视频&#xff0c;曾经是一件既费钱又费时的事情。要么外…...

如何用Python脚本实现剪映自动化:JianYingApi技术深度解析

如何用Python脚本实现剪映自动化&#xff1a;JianYingApi技术深度解析 【免费下载链接】JianYingApi Third Party JianYing Api. 第三方剪映Api 项目地址: https://gitcode.com/gh_mirrors/ji/JianYingApi 面对视频剪辑中的重复性劳动&#xff0c;你是否渴望解放双手&am…...