WPF性能优化:Freezable 对象
Freezable是WPF中一个特殊的基类,用于创建可以冻结(Freeze)的可变对象。冻结一个对象意味着将其状态设置为只读,从而提高性能并允许在多线程环境中共享对象。
Freezable的应用
我们定义画刷资源的时候常常会这样写:
<SolidColorBrush x:Key="RedBrush" Color="Red" o:Freeze="True"/>
代码中的o:Freeze="True"其实就是使用Freezable的 Freeze方法冻结画刷,使之不可修改,系统不必监视该画刷对象,从而减少资源消耗。
o:Freeze="True"乍一看像附加属性,其实并不是的。Freeze属性是http://schemas.microsoft.com/winfx/2006/xaml/presentation/optionsXML命名空间中定义的唯一属性或其他编程元素。Freeze属性专门存在于此特殊命名空间中,以便在根元素声明中可以使用。处理Freeze属性的功能专门内置于处理已编译应用程序的 XAML的XAML处理器中。
那是不是WPF中的所有资源都可以(需要)使用Freeze方法冻结来提高性能呢?
Freezable类通常用于WPF中的资源和动画,例如创建可重用的画刷、几何图形和动画。从Freezable继承的类型包括Brush、Transform和Geometry类。由于它们包含非托管资源,因此系统必须监视这些对象发生的修改,然后在原始对象发生更改时更新对应的非托管资源。即使实际上并未修改图形系统对象,系统仍必须消耗一些资源来监视该对象,以防更改它。
例如,假设创建一个SolidColorBrush画笔并用它来绘制按钮的背景。
<Window.Resources>
<SolidColorBrush x:Key="RedBrush" Color="Red"/>
</Window.Resources>
<Button Background="{StaticResource RedBrush}"/>
呈现按钮时,WPF图形子系统使用你提供的信息来绘制一组像素,以创建按钮的外观。尽管使用纯色画笔来描述按钮的绘制方式,但纯色画笔实际上并没有进行绘制。图形系统为按钮和画笔生成快速、低级别的对象,实际显示在屏幕上的就是这些对象。
如果要修改画笔,则必须重新生成这些低级别对象。Freezable类使画笔能够找到生成的相应低级别对象并在更改时更新它们。
注意事项
并非每个Freezable对象都可以冻结。为避免引发InvalidOperationException,请在尝试冻结Freezable对象之前检查该对象的CanFreeze属性值,以确定是否可以将其冻结。如果满足以下任一条件,则无法冻结Freezable:
- 它具有动画属性或数据绑定属性。
- 它具有由动态资源设置的属性。
- 它包含无法冻结的Freezable子对象。
Freezable对象调用Freeze方法冻结后,就无法解冻。修改冻结对象属性时会引发InvalidOperationException。但是,可以使用Clone或CloneCurrentValue方法创建(深拷贝)解冻的副本。如果Freezable包含其他已冻结的 Freezable对象,它们也会被克隆并变为可修改。
无论使用哪种克隆方法,动画都不会复制到新的 Freezable。
由于无法对冻结的Freezable进行动画处理,因此使用Storyboard对其进行动画处理时,动画系统会自动创建冻结的Freezable对象的可修改克隆。为了消除克隆导致的性能开销,如果需要对对象进行动画处理,请让其保持解冻状态。
附加属性实现XAML中Freeze
上文中提到o:Freeze="True"并不是通过附加属性实现,而是内置于XAML处理器中实现。我们自己也可以通过附加属性的方式实现,代码如下:
public class PresentationOptionsAttach
{
public static bool GetFreeze(Freezable freezable)
{
return (bool)freezable.GetValue(FreezeProperty);
}
public static void SetFreeze(Freezable freezable, bool value)
{
freezable.SetValue(FreezeProperty, value);
}
public static readonly DependencyProperty FreezeProperty =
DependencyProperty.RegisterAttached("Freeze", typeof(bool), typeof(PresentationOptionsAttach), new PropertyMetadata(false, OnFreezeChanged));
private static void OnFreezeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (DesignerProperties.GetIsInDesignMode(d)) return;
if ((bool)e.NewValue)
{
Freezable freezable = d as Freezable;
if (freezable.CanFreeze)
freezable.Freeze();
}
}
}
小结
Freezable是一个我们既熟悉又陌生的类,熟悉是因为我们经常使用,陌生是因为很少关注其优化性能的机制以及需要注意的地方。本文简单介绍了Freezable优化性能的机制以及注意事项,并提供了通过附加属性的方式在XAML中冻结资源。
WPF性能优化:Freezable 对象的更多相关文章
- WPF性能优化经验总结
WPF性能优化一.Rendering Tier 1. 根据硬件配置的不同,WPF采用不同的Rendering Tier做渲染.下列情况请特别注意,因为在这些情况下,即使是处于Rendering Tie ...
- WPF性能优化的一些建议
尽量多使用Canvas等简单的布局元素,少使用Grid或者StackPanel等复杂的,减小开销. 少用Margin Padding尤其避免嵌套使用. 在自定义控件,尽量不要在控件的ResourceD ...
- Freezable 对象(WPF)
# Freezable 对象(WPF) # > Freezable 继承自 DependencyObject,同时添加了 Freezable 方法,用于冻结对象. --- ## 冻结对象 ## ...
- c#+wpf项目性能优化之OutOfMemoryException解密
近期,使用c#+wpf开发的软件准备正式投入使用了,使用前进行了大量的测试,测试后发现了一些问题,其中最让人头疼的就是软件的性能问题(稳定性). 这里的稳定性具体表现在机器的cpu占有率和内存使用情况 ...
- .NET性能优化-ArrayPool同时复用数组和对象
前两天在微信后台收到了读者的私信,问了一个这样的问题,由于私信回复有字数和篇幅限制,我在这里统一回复一下.读者的问题是这样的: 大佬您好,之前读了您的文章受益匪浅,我们有一个项目经常占用 7-8GB ...
- WPF性能提高--MSDN学习摘要
关于性能 一. 关于硬件加速 1.对于大多数图形硬件而言,大型图面是指达到 2048x2048 或 4096x4096 像素大小的图面. 二. 合理的布局 1.简单地说,布局是一个递归系统 ...
- Freezable 对象概述 | Microsoft Docs
原文:Freezable 对象概述 | Microsoft Docs Freezable 对象概述Freezable Objects Overview 2017/03/30 本文内容 什么是可冻结的? ...
- EntityFramework之异步、事务及性能优化(九)
前言 本文开始前我将循序渐进先了解下实现EF中的异步,并将重点主要是放在EF中的事务以及性能优化上,希望通过此文能够帮助到你. 异步 既然是异步我们就得知道我们知道在什么情况下需要使用异步编程,当等待 ...
- C#性能优化实践
性能主要指两个方面:内存消耗和执行速度.性能优化简而言之,就是在不影响系统运行正确性的前提下,使之运行地更快,完成特定功能所需的时间更短. 本文以.NET平台下的控件产品MultiRow为例,描述C# ...
- C#性能优化实践【转】
性能主要指两个方面:内存消耗和执行速度.性能优化简而言之,就是在不影响系统运行正确性的前提下,使之运行地更快,完成特定功能所需的时间更短. 本文以.NET平台下的控件产品MultiRow为例,描述C# ...
随机推荐
- 白嫖一个WebAPI限流解决方案
什么是API限流: API 限流是限制用户在一定时间内 API 请求数量的过程.应用程序编程接口 (API) 充当用户和软件应用程序之间的网关.例如,当用户单击社交媒体上的发布按钮时,点击该按钮会触发 ...
- 曲线艺术编程 coding curves 第十四章 其它曲线(Miscellaneous Curves)
第十四章 其它曲线(Miscellaneous Curves) 原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ ...
- Stable Diffusion AIGC:3步成为P图大师
摘要:instructPix2Pix文字编辑图片是一种纯文本编辑图像的方法,用户提供一张图片和文本编辑指令,告诉模型要做什么,模型根据编辑指令编辑输入的图像,最终输出用户想要的图像. 本文分享自华为云 ...
- 【Springboot】SpringBoot-Admin 服务监控+告警通知
SpringBoot-Admin 服务监控 简单介绍 Spring Boot Actuator 是 Spring Boot 自带的一个功能模块, 提供了一组已经开箱即用的生产环境下常用的特性和服务,比 ...
- 【SpringBoot】 集成 Ehcache
SpringBoot ehcache 缓存 简介 EhCache 是一个纯 Java 的进程内缓存框架,具有快速.精干等特点, 是 Hibernate 中默认CacheProvider.Ehcache ...
- 【Docker】迷你使用手册
一.安装与配置 安装: # Centos7 yum install docker 启动 & 设为开机启动: systemctl start docker.service systemctl e ...
- influxdb 保留策略
转载请注明出处: InfluxDB 中的保留策略用于定义时间序列数据在数据库中的保留期限.保留策略决定了数据在 InfluxDB 中的存储持续时间和精度.以下是 InfluxDB 的保留策略类型以及如 ...
- linux内核编译体验篇(一)
文章目录 一. 准备环境 二. 获取内核源码 三. 交叉编译工具链的配置 1. 博友们常用安装方法链接 2. 公司常用的交叉工具链使用方法 四. 内核解压以及如何打补丁 五. 内核基本配置 1. 编译 ...
- 【译】Visual Studio 2022 中的 Web API 开发
在 Visual Studio 2022 中,Web 开发人员的主要场景之一是使用 ASP.NET Core 创建 Web API.在 Visual Studio 2022 17.6 的最新预览版中, ...
- 西门子HMI切换页面时的指示功能
怎么样才能做到像这样按下切换界面的按钮,切换过去之后对应的切换按钮还进行高亮指示呢? 首先我们要先新建模板,把我们的画面拖拽到模板里就会形成按钮 在画面的"属性"中 在属性中选上我 ...