WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系,越高档的机器性能越有优势。

程序性能改善不是一蹴而就的,好的设计可以消除影响性能的问题,例如,在运行时构造对象就会对程序的性能造成影响。虽然WPF通过增强的导航等功能提供了更丰富的用户界面,但你应该考虑你的用户是否的确需要富图形界面,尽管WPF有这样那样的问题,但在UI设计,特别是自定义风格和控件模板方面,的确给开发人员提供了不少灵活性。

渲染WPF程序的主要因素是它包含的像素量,WPF使用微软的DirectX在程序运行的硬件上进行渲染,因此,如果你的机器有独立显卡,运行WPF程序会更流畅。除了提高硬件配置外,我们来看看10个提高WPF程序性能的软方法。

      1、降低Bitmapscalingmode,加速图像渲染

      当你的WPF程序中包含有动画时,你可以使用RenderOptions对象的BitmapScalingMode属性降低资源消耗,需要将BitMapScalingMode属性的值设为LowQuality,这样就会使用加速算法处理图像,而不是默认的高质量图像重采样算法。下面的代码片段显示了最基本的实现方法:

RenderOptions.SetBitmapScalingMode(imageObject,BitmapScalingMode.LowQuality);

      2、在正确的地方使用正确的元素

我们需要在正确的地方使用正确的元素,当你生成树时应避免使用UIElements作为子或嵌套控件,最好的例子是FlowDocument,我们经常在FlowDocument中使用TextBlock元素。

<FlowDocument>
<Paragraph>
<TextBlock>some text</TextBlock>
</Paragraph>
</FlowDocument>

除了上面这样写外,我们还可以象下面这样重写XAML内容,Run元素不是UIElement,渲染时系统开销更小。

<FlowDocument><Paragraph><Run>some text</Run></Paragraph></FlowDocument>

类似的例子是使用Label控件的Content属性,如果在其生命周期内内容不止更新一次,并且是个字符串,这个数据绑定过程可能会阻碍程序的性能,由于内容是一个字符串,在数据绑定期间它会被丢弃,并重新创建。在这种情况下使用TextBlock将数据绑定到Text属性更有效。

在可视化树中出现不必要的元素也会降低WPF程序的速度,你最好结合布局优化默认的控件模板。

      3、增加静态资源的使用

静态资源是预定义的资源,可以连接到XAML属性,它类似于编译时绑定,不会影响性能,另一方面,动态资源涉及到运行时查找和对象的构建,从而会影响到性能。但也需要注意,静态资源需要在编译时展示。

静态资源的引用可以参考下面的方法:

<Button
Template="{StaticResource RoundButtonWithThickEdge}"
x:Name="button1" Content="Button 1" >
</Button>

下面的代码片段显示了静态资源RoundButtonWithThickEdge的定义:

<ControlTemplate
x:Key="RoundButtonWithThickEdge"
TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"
Stroke="{x:Null}"
HorizontalAlignment="Stretch" x:Name="ellipse"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Ellipse Stroke="{x:Null}" Margin="2,3,4,5">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFBFAFA" Offset=""/>
<GradientStop Color="#1DFFFFFF" Offset=""/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>

      4、当你想显示大型数据时,使用UI虚拟化的控件

想象一下一个组合框绑定大量行时的样子,它会让组合框中项目的展现变得非常慢,这是因为在这种情况下,程序需要计算每个项目的具体显示位置,使用WPF时,你可以延迟这个行为,这就叫做UI虚拟化,它只会在其可见范围内生产项目显示需要的容器。

要实现这种效果,你需要将相应控件的IsVirtualizing属性设为True,例如,Listbox经常用来绑定大型数据集,它是UI虚拟化的重要候选者,其它适宜UI虚拟化的控件包括Combobox,ListView和TreeView。

      5、使用延迟滚动增强用户体验

如果你还记得可滚动的DataGrid或ListBox,它们往往会降低整个应用程序的性能,因为在滚动时会强制连续更新,这是默认的行为,在这种情况下,我们可以使用控件的延迟滚动(Deferred Scrolling)属性增强用户体验。你需要做的仅仅是将IsDeferredScrollingEnabled附加属性设为True。

      6、使用字体缓存服务提高启动时间

WPF应用程序之间可以共享字体数据,它是通过一个叫做PresentationFontCache Service的Windows服务实现的,它会随Windows自动启动。

  你可以在控制面板的“服务”中找到这个服务(或在“运行”框中输入Services.msc),确保这个服务已经启动。

      7、使用卸载事件卸载不必要的动画

动画肯定会占用一定的资源,如果处置方式不当,将会消耗更多的资源,如果你认为它们无用时,你应该考虑如何处理他们,如果不这样做,就要等到可爱的垃圾回收器先生来回收资源。

  例如,假设要删除一个StoryBorad,在Unload事件中使用StoryBorad的Remove方法,下面的例子来自MSDN。

<EventTrigger RoutedEvent="Page.Unloaded" >
<EventTrigger.Actions>
<RemoveStoryboard BeginStoryboardName="myBeginStoryboard" />
</EventTrigger.Actions>
</EventTrigger>

      8、使用容器回收提高性能

你可以通过回收执行虚拟化的容器来提高性能,下面的代码片段将ViruatlizationMode设为Recycling,它让你可以获得更好的性能。当用户滚动或抵达另一个项目时,它强制重复使用容器对象。

settingVirtualizingStackPanel.VirtualizationMode="Recycling"

      9、预测图像绘制能力

使用RenderCapability.Tier属性确定机器是支持硬件加速,还是部分硬件加速,疑惑没有硬件加速,下面的代码显示了你要如何检查Tier。

int displayTier = (System.Windows.Media.RenderCapability.Tier > )

  if (displayTier == )
{
//no hardware acceleration
}
else if (displayTier == )
{
//partial hardware acceleration
}
else
{
//supports hardware acceleration
}

确定了之后,你就可以有选择性地选择那些在用户硬件上工作得很好的功能

      10、使用WPF分析工具分析WPF程序

分析WPF程序是理解其行为很重要的一步,市场上有大量现成的WPF程序分析工具,如Snoop,WPFPerf,Perforator和Visual Profiler,其中Perforator和Visual Profiler是WPF Performance Suite的一部分,要了解这些工具的用法,请去它们的项目主页。

细数改善WPF应用程序性能的10大方法的更多相关文章

  1. 改善WPF应用程序性能的10大方法 (转发)

    WPF(Windows Presentation Foundation)应用程序在没有图形加速设备的机器上运行速度很慢是个公开的秘密,给用户的感觉是它太吃资源了,WPF程序的性能和硬件确实有很大的关系 ...

  2. 提高ASP.NET应用程序性能的十大方法

    一.返回多个数据集 检查你的访问数据库的代码,看是否存在着要返回多次的请求.每次往返降低了你的应用程序的每秒能够响应请求的次数.通过在单个数据库请求中返回多个结果集,可以减少与数据库通信的时间,使你的 ...

  3. 提高Asp.Net应用程序性能的十大方法(译感)

    译完了提高Asp.Net应用程序的十大方法这篇文章,仔细想其中提到的每一条,在这里结合我的项目来谈谈.第一条:返回多个结果集因为我的项目中所有对数据库的访问的sql语句都是通过调用存储过程实现的,所以 ...

  4. Web标准中用于改善Web应用程序性能的各种方法总结

    提起Web应用程序中的性能改善,广大开发者们可能会想到JavaScript与DOM访问等基于各种既存技术的性能改善方法.最近,各种性能改善方法被汇总成为一个Web标准. 本文对Web标准中所包含的各种 ...

  5. 提高 Web开发性能的 10 个方法

    随着网络的高速发展,网络性能的持续提高成为能否在芸芸App中脱颖而出的关键.高度联结的世界意味着用户对网络体验提出了更严苛的要求.假如你的网站不能做到快速响应,又或你的App存在延迟,用户很快就会移情 ...

  6. 优化iOS程序性能的25个方法

    1. 用ARC管理内存 ARC(Automatic ReferenceCounting, 自己主动引用计数)和iOS5一起公布.它避免了最常见的也就是常常是因为我们忘记释放内存所造成的内存泄露.它自己 ...

  7. 细数vue爬坑之路<坑路大集合>

    坑爹集锦一: npm出现Newline required at end of file but not found错误 原因:eslint语法错误(vue为后缀名的组件结尾没有换行) 解决办法:在结尾 ...

  8. 提高ASP.NET首页性能的十大方法

    本文是我对ASP.NET页面载入速度提高的一些做法,这些做法分为以下部分: http://www.cnblogs.com/xiachufeng/archive/2011/11/09/2242130.h ...

  9. [转]成为优秀Java程序员的10大技巧

    转自:http://www.codeceo.com/article/10-good-java-programmer-tips.html Java程序员有许多应遵循的守则或最佳实践方式.本文概述了每个开 ...

随机推荐

  1. vs调试断点进不去的解决办法

    原创文章,禁止转载. 断点进不去的解决办法:  确认是debug版本  确认生成了调试信息  确认在编译和连接的工程配置中指定了相同的匹配的pdb文件名,而不是默认的vc100.pdb等名字(无关) ...

  2. mysql 5.7开启并行复制

    开启多线程复制,默认关键的参数有两个: mysql> show variables like 'slave_parallel_%'; +------------------------+---- ...

  3. ArcGIS Js/Flex等前端API(Query(StatisticDefinition)时)针对SDE的SHAPE.AREA/SHAPE.LEN知道查询无效,而对GDB的SHAPE_Area/SHAPE_Length有效探索。

    FIeld 'SHAPE.AREA' and 'SHAPE.LEN' of SDE For Oracle,Field 'SHAPE_Area' and 'SHAPE_Length' of gdb(ge ...

  4. ODBC,OLEDB,ADO,ADO.net,JDBC 理解

    一 .ODBC 开放式数据库互联(Open Database connectivity), 93年微软推出的实现应用程序 和关系数据库直接 通讯的借口标准.只能用于关系数据库 . 注意事项 : 必须先 ...

  5. 有一种感动叫ACM(记陈立杰在成都赛区开幕式上的讲话)

    各位选手,各位教练,大家好,我是来自清华大学交叉信息学院的陈立杰,今天很荣幸站在这里代表全体参赛选手发言.对于我来说,这是我第一次正式参加ACM的比赛.不过我跟ACM之间的缘分,大概在很早的时候就已经 ...

  6. fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "StdAfx.h"”? 解决方法

    错误描述: fatal error C1010: 在查找预编译头时遇到意外的文件结尾.是否忘记了向源中添加“#include "StdAfx.h"”? 错误分析:     此错误发 ...

  7. SpringAOP代理报错问题

    public class BaseDataSyncPushJob implements StatefulJob{ /*** 日志 */ private static final Log LOG = L ...

  8. java面向对象(封装-继承-多态)

    框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...

  9. 20145301&20145321&20145335实验五

    20145301&20145321&20145335实验五 这次实验我的组员为:20145301赵嘉鑫.20145321曾子誉.20145335郝昊 实验内容详见:实验五

  10. Unity3d中Update()方法的替身

    在网上看到一些资料说Unity3d的Update方法是如何如何不好,影响性能.作为一个菜鸟,之前我还觉得挺好用的,完全没用什么影响性能的问题存在.现在发现确实有很大的问题,我习惯把一大堆检测判断放在U ...