首页 > 系统相关 >WPF在EnsureHandle之前设置WindowStyle提升性能

WPF在EnsureHandle之前设置WindowStyle提升性能

时间:2023-09-02 15:23:51浏览次数:51  
标签:WindowStyle 窗口 Win32 设置 WPF EnsureHandle 属性

本文将记录一个在 WPF 应用程序启动过程中的性能优化点。如果一个窗口需要设置 WindowStyle 属性,那么在窗口 EnsureHandle 之前,设置 WindowStyle 属性将会比在 EnsureHandle 之后设置快不少

在 dotTrace 里的一次测量在窗口 EnsureHandle 之后设置 WindowStyle 属性的时间大概是 200 毫秒,这个时间在启动过程中可以被认为是非常长的时间,而且这还是一个在 UI 线程上的时间。以下是 dotTrace 测量结果

可以看到在窗口 EnsureHandle 之后设置 WindowStyle 属性,需要等待 Win32 窗口的响应。再阅读 WPF 源代码,可以看到在窗口 EnsureHandle 之后设置 WindowStyle 属性,就需要等待 HwndStyleManager 的 Dispose 方法。以下是 WPF 的源代码

看起来这是非常合理的耗时,在 Win32 窗口创建出来之后,也就是对应 EnsureHandle 拿到窗口句柄之后,这时如果设置 WindowStyle 属性,就需要同步给到 Win32 窗口。为了同步设置给到 Win32 窗口,自然就需要等待 Win32 窗口处理了,对应的就是以上代码的等待渲染线程挂载窗口的一次渲染逻辑。这里需要说明的是上文说的等待渲染线程挂载窗口的一次渲染逻辑是我的猜测,根据 wpfgfx_cor3.dll 以及 SyncFlush 方法进行猜测的

在 EnsureHandle 之前设置 WindowStyle 则可以规避以上路径从而提升性能。提升性能的原因是在 EnsureHandle 之前,也就是 Win32 窗口创建之前,对 WindowStyle 的赋值走的是一个简单的属性赋值,毫无性能损耗。在真正创建窗口时,才读取 WindowStyle 属性,根据属性去创建 Win32 窗口。由于 WPF 应用本来就需要创建 Win32 窗口,也就是此时对 WindowStyle 的设置本身是不影响 Win32 窗口的创建的,换句话说就是在 Win32 窗口创建之前设置 WindowStyle 约等于免费

那在启动完成之后,窗口渲染完成之后设置 WindowStyle 呢?此时基本上不需要等待渲染,设置 WindowStyle 也就是一个 Win32 函数调用的损耗,大概测量时间在 30ms 左右。也就是说只有在启动过程中,想要做性能优化,才需要关注 EnsureHandle 之前设置 WindowStyle 属性。本文以上测试由 lsj 提供

标签:WindowStyle,窗口,Win32,设置,WPF,EnsureHandle,属性
From: https://www.cnblogs.com/lindexi/p/17673705.html

相关文章

  • WPF引入Metro后默认样式被更改,想使用原始样式的办法
    参考WPF引入HandyControl后默认样式被更改,想使用原始样式的办法_冰激凌克星的博客-CSDN博客<ButtonStyle="{x:Null}"Content="取消HandyControl样式"Margin="20"/>将Style设置成null......
  • WPF使用Blazor的快速案例
    下面我们将讲解在WPF中使用Blazor,并且使用Blazor做一些文件编辑操作,下面是需要用到的东西WPFBlazorMasaBlazorMonaco安装MasaBlazor模板使用CMD指令安装模板dotnetnewinstallMASA.Template新建MasaBlazorWPFApp找到如图的模板,然后点击下一步下一步,新建......
  • WPF 动态更改启动窗体startupUri
    第一步:在App.xaml里,把StartupUri=""去掉,改成Startup="Application_Startup"第二步:在App.xaml.cs里,增加Application_Startup事件:privatevoidApplication_Startup(objectsender,StartupEventArgse){ApplicationcurrApp=Application.Current;currAp......
  • WPF Textblock标签下 Run标签-----显示空白或者消除空白
    消除Run之前的空白是将Run标签布局时头尾相连,如下:<TextBlock><RunText="A"></Run><RunText="B"></Run></TextBlock> 消除Run之间连接的空白格式,方式如下:<TextBlock><RunText="A&quo......
  • WPF设置传参、点击按钮改变长度
    前台代码<!--通过传递ElementName--><Buttonx:Name="btn1"Width="200"Height="27"Command="{BindingCommand}"CommandParameter="{BindingElementName=btn1}"/><!--......
  • C# wpf 实现窗口靠近屏幕边缘自动吸附
    参考:https://blog.csdn.net/qq_35831134/article/details/88751067#region侧吸privatenewboolHide=false;//用来表示当前隐藏状态,例如Hide=false就是不在隐藏状态stringtype="";//用来表示窗口隐藏在哪个方向pri......
  • 为WPF按钮添加UAC盾牌图标
    在上一篇文章中,介绍了如何获取系统Shell的图标。在C#中调用SHGetStockIconInfo即可获取获取图标 定义SHGetStockIconInfo函数用到的数据结构1publicenumSHSTOCKICONID:uint2{3///<summary>Documentofatypewithnoassociatedapplicatio......
  • WPF-封装自定义雷达图控件
     源码地址:https://gitee.com/LiuShuiRuoBing/code_blog雷达图用于表示不同内容的占比关系,在项目中有广泛的应用,但是目前未曾有封装良好的雷达图控件,鉴于最近项目的使用,于是想要封装一个通用的雷达图控件,便于日后的扩展使用。首先雷达图的绘制大概分为雷达图的图层、......
  • WPF使用TextBlock实现查找结果高亮显示
    在应用开发过程中,经常遇到这样的需求:通过关键字查找数据,把带有关键字的数据显示出来,同时在结果中高亮显示关键字。在web开发中,只需在关键字上加一层标签,然后设置标签样式就可以轻松实现。在WPF中显示文本内容通常采用TextBlock控件,也可以采用类似的方式,通过内联流内容元素Run达到......
  • wpf路由事件简述
    比如在一个窗体中放一个容器,容器中再放一个按钮,添加按钮的鼠标点击事件,再添加容器的鼠标点击事件,然后添加窗体的鼠标点击事件,那么当我们触发按钮的鼠标点击事件后如果不设置e.handle=true就会继续执行容器的鼠标点击事件然后再执行窗体的鼠标点击事件,这就是路由事件的概念。......