WPF 应用程序性能优化
- 开发效率:能使用XAML实现的就不用户CS后台程序编写
- 数据绑定:数据绑定使用的是属性,不是字段
public ObservableCollection<string> list { get; set; } = new ObservableCollection<string>();
Dispatcher.Invoke(() => { list.Add(i.ToString()); }, DispatcherPriority.Background);
- 防止卡顿:使用BackgroundWorker防止UI卡顿,BackgroundWorker组件提供了一种执行异步操作(后台线程)的同时还能显示操作进度的解决方案。
BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += (o, e) => { }; worker.RunWorkerCompleted += (o, e) => { }; worker.RunWorkerAsync();
- 通知主线程:Dispatcher.Invoke(() => { }) 或者 Dispatcher.InvokeAsync(() => { }) 或者 Dispatcher.BeginInvoke(() => { }),Invoke会阻塞线程,直到Invoke里的代码完成,InvokeAsync异步执行, BeginInvoke后台运行代码。
- 避免将数据绑定到Label.Content属性,如果使用标签将数据绑定到String属性,这将导致性能下降。这是因为每次更新String源时,都会丢弃旧的字符串对象,并创建一个新的String。如果Label的内容是简单文本,则将其替换为TextBlock,然后绑定到Text属性。
- 画笔上的不透明度而不是元素,如果使用“画笔”设置元素的“填充”或“描边”,则最好在“画笔”上设置“不透明度”,而不是设置元素的“不透明度”属性。修改元素的“不透明度”属性时,它可能导致WPF创建临时曲面,从而导致性能下降。
- 使用缩小的图像尺寸,如果您的应用要求显示较小的缩略图,请考虑创建缩小尺寸的图像。默认情况下,WPF将加载并解码图像到其完整尺寸。如果要加载完整的图像并将它们缩小到ItemsControl等控件中的缩略图大小,这可能是许多性能问题的根源。如果可能,将所有图像合并为一个图像,例如由多个图像组成的胶片。
- 降低BitMapScalingMode,默认情况下,WPF使用高质量的图像重采样算法,该算法有时会消耗系统资源,这会导致帧速率下降并导致动画停顿。而是将BitMapScalingMode设置为LowQuality,以从“质量优化”算法切换为“速度优化”算法。
- 在单独的线程上加载数据,性能问题,UI冻结以及停止响应的应用程序的一个非常常见的来源是如何加载数据。确保您在一个单独的线程上异步加载数据,以免UI线程超载。在UI线程上加载数据将导致非常差的性能以及最终用户的整体体验。每个WPF开发人员都应在其应用程序中使用多线程。
- 内存泄露主要原因分析:静态引用、未注销的事件绑定、非托管代码资源使用等。对于静态对象尽量小或者不用,非托管资源可通过手动Dispose来释放。
- 使用MVVM模式绑定DataContext或是直接给列表控件绑定数据源的情况下,关闭窗体时,最好将绑定属性赋一个空值
protected override void OnClosed(EventArgs e) { base.OnClosed(e); this.DataContext = null; }
-
对Image做动画处理的时候(如调整大小等),可以使用这条语句RenderOptions.SetBitmapScalingMode(MyImage,BitmapScalingMode.LowQuality)
<Image RenderOptions.BitmapScalingMode="NearestNeighbor" RenderOptions.ClearTypeHint="Enabled" />
RenderOptions.SetBitmapScalingMode(Img,BitmapScalingMode.NearestNeighbor); RenderOptions.SetClearTypeHint(Img,ClearTypeHint.Enabled);
-
图片处理:下载远程图片到本地文件夹,把文件夹图片放到内存,使用图片从内存取出;