【问题标题】:Improve performance in big project c# WPF XAML [closed]提高大型项目 c# WPF XAML 的性能 [关闭]
【发布时间】:2020-02-25 08:40:30
【问题描述】:

我们公司有一个用 C# + WPF + XAML 编写的产品(程序)。这对我们来说是一个相当重要的程序,我们的许多客户已经安装了它。但在切换到 Framework 4.7.2 后,我们注意到性能大幅下降。然后我们改到了 4.8 版本,但是程序运行起来还是很慢,尤其是视觉部分。

在我们的程序中,我们显示来自大量传感器(运动传感器、温度、光量等)的数据。我们不断收到我们处理的新数据,保存到 SQL Server 2014/2017 数据库,然后客户端程序将这些数据可视化。

服务器部分和通信虽然复杂,但即使在功能不太强大的计算机上也能正常工作。但是我们在客户监视器上显示数据时遇到了一个非常大的问题。

程序的结构如下:客户在他想看到这些数据的地方画图。例如,他有黑色背景,用线条画出他的工厂。这家工厂的不同地方都有传感器,他在这些地方画了它们。然后他开始扫描并查看他绘制标签的数据结果。数据少的时候不是很明显,但是数据多的时候鼠标在数据之间移动就被禁止了,客户端看到程序一直在变慢,需要等几秒,make用鼠标进行一些移动,然后再次等待程序响应。如果你一次做几件事,那么程序就好像冻结了一样。不是这样,但感觉程序现在将停止工作。

我尝试使用调试和测量 CPU 和 RAM,但它实际上对我没有任何帮助。数据通常通过 Web 服务从服务器下载到客户端程序,并根据需要占用尽可能多的内存。很难以某种方式对其进行优化。但是当我们开始向用户展示这些数据时,一切都开始变得很糟糕。如何优化数据可视化,让用户继续冷静地使用程序?很乐意接受任何建议。

我所做的对改进 DataGrid 表中的虚拟化有所帮助。对用户来说稍微好一点,但这还不够,您还需要其他东西,尤其是绘制的部分,并在不同位置显示带有数据的标签。

【问题讨论】:

  • 请与我们分享一些细节,例如代码和性能指标,让您的问题更加具体
  • 你之前用的是什么框架版本?
  • @Edgaras 首先我们使用 Framework 4.5,而不是 4.6 并且正常工作。但是4.7.2之后性能会变差。

标签: c# sql-server wpf web-services xaml


【解决方案1】:

根据我的经验,wpf 不适合可视化大量数据。创建精美的 UI 很好,但随着对象数量的增加,性能会急剧下降。我尝试了从缓存到冻结对象的所有方法,但我得出的结论是我选择了错误的技术。它没有正确利用您的 GPU。

您可以尝试转换为 UWP,它可能会有所帮助。

话虽如此,您也可以尝试以下提示:

  1. 简化您的可视化树 性能问题的常见来源是深度和复杂的布局。使您的 XAML 标记保持简单和浅薄 尽可能。当在屏幕上绘制 UI 元素时,“布局通道”是 为每个元素调用两次(测量通道和排列通道)。 布局过程是一个数学密集型过程——越大 元素中子元素的数量,数量越大 需要计算。

  2. 虚拟化您的 ItemsControls 如前所述,复杂而深入的可视化树会导致更大的内存占用和更慢 表现。 ItemsControls 通常会增加性能问题 深度视觉树,因为它们没有被虚拟化。这意味着他们 中的每个项目都在不断地被创建和销毁 控制。相反,使用 VirtualizingStackPanel 作为项目主机和 利用 VirtualizingStackPanel.IsVirtualizing 并设置 VirtualizationMode 到 Recycling 以重用项目容器 而不是每次都创建新的。

  3. StaticResources 优于 DynamicResources StaticResources 通过查找对 已经定义的资源。该资源的查找行为是 与编译时查找相同。 DynamicResources 将创建一个 临时表达式并推迟查找资源,直到 请求的资源值是必需的。查找行为 资源与运行时查找相同,它强加了性能 影响。尽可能始终使用静态资源。

  4. 画笔而不是元素的不透明度 如果使用画笔设置元素的填充或描边,最好将不透明度设置为 Brush 而不是设置元素的 Opacity 属性。当你 修改元素的 Opacity 属性,会导致 WPF 创建 导致性能下降的临时表面。

  5. 避免使用 Run 来设置文本属性 避免在 TextBlock 中使用 Run,因为这会导致更高的性能密集型 手术。如果您使用 Run 来设置文本属性,请设置那些 而是直接在 TextBlock 上。

  6. 优先使用 StreamGeometry 而非 PathGeometry StreamGeometry 对象是 PathGeometry 的一个非常轻量级的替代方案。 StreamGeometry 针对处理许多 PathGeometry 对象进行了优化。它 与使用相比,消耗更少的内存并且性能更好 许多 PathGeometry 对象。

  7. 使用缩小的图像尺寸 如果您的应用需要显示更小的缩略图,请考虑创建缩小尺寸的图像版本。 默认情况下,WPF 会将您的图像加载并解码为其完整大小。这 如果您加载完整,可能是许多性能问题的根源 图像并将它们缩小到控件中的缩略图大小,例如 项目控制。如果可能,将所有图像组合成一个图像, 例如由多个图像组成的胶片。

  8. 降低 BitMapScalingMode 默认情况下,WPF 使用高质量的图像重采样算法,有时会消耗系统 导致帧速率下降的资源,并导致 动画口吃。相反,将 BitMapScalingMode 设置为 LowQuality 从“质量优化”算法切换到 “速度优化”算法。

  9. 使用和冻结 Freezables Freezable 是一种特殊类型的对象,它有两种状态:未冻结和冻结。当你冻结一个物体时 例如画笔或几何图形,它不能再被修改。冷冻 尽可能提高应用程序的性能 并减少其内存消耗。

  10. 修复绑定错误 绑定错误是 WPF 应用程序中最常见的性能问题类型。每次发生绑定错误时, 您的应用程序受到了性能打击,因为它试图解决绑定和 将错误写入跟踪日志。可以想象,越 绑定错误对应用程序的性能影响越大 拿。花时间查找并修复所有装订错误。用一个 DataTemplates 中的 RelativeSource 绑定是绑定的罪魁祸首 错误,因为绑定通常不会正确解决,直到 DataTempate 已完成初始化。避免使用 不惜一切代价的RelativeSource.FindAncestor。相反,定义一个附加的 属性并使用属性继承将值下推视觉 树而不是查找可视化树。

  11. 避免对 Label.Content 属性进行数据绑定 如果您使用 Label 将数据绑定到 String 属性,这将导致不良 表现。这是因为每次更新 String 源时, 旧的字符串对象被丢弃,并创建一个新的字符串。如果 Label 的 Content 是简单的文本,用 TextBlock 替换它 并改为绑定到 Text 属性。

  12. 将 ItemsControls 绑定到 IList 而不是 IEnumerable 当数据将 ItemsControl 绑定到 IEnumerable 时,WPF 将创建一个包装器 IList 类型对性能产生负面影响的 创建第二个对象。相反,直接绑定 ItemsControl 到 IList 以避免包装对象的开销。

  13. 使用 NeutralResourcesLanguage 属性 使用 NeutralResourcesLanguageAttribute 告诉 ResourceManager 中立文化是并避免不成功的卫星装配查找。

  14. 在单独的线程上加载数据 性能问题、UI 冻结和应用程序停止响应的一个非常常见的来源是加载 你的数据。确保您将数据异步加载到 单独的线程,以免 UI 线程过载。加载数据到 UI 线程会导致性能很差,整体不好 最终用户体验。多线程应该是每个 WPF 的东西 开发人员正在他们的应用程序中使用。

  15. 注意内存泄漏 内存泄漏是大多数 WPF 应用程序中性能问题的第一大原因。他们很容易拥有 但可能很难找到。例如,使用 DependencyPropertyDescriptor.AddValueChanged 会导致 WPF 框架对事件源进行强引用 在您手动调用之前不会被删除 DependencyPropertyDescriptor.RemoveValueChanged。如果您的观点或 行为依赖于从对象或 ViewModel 引发的事件 (如 INotifyPropertyChanged),弱订阅或制作 确保您手动取消订阅。此外,如果您绑定到 未实现的 ViewModel 中的属性 INotifyPropertyChanged,你可能有内存泄漏。

最后,一个额外的小费。有时当你遇到性能问题时 可能很难确定究竟是什么导致了问题。一世 建议使用应用程序性能分析器来帮助识别 这些性能瓶颈出现在您的代码库中。 您可以使用许多分析器选项。有些是有偿的, 有些是免费的。我个人使用最多的是诊断 直接内置于 Visual Studio 2019 中的工具。 块引用

来源:https://dzone.com/articles/15-wpf-performance-tips-for-2019

【讨论】:

  • 我不知道你从哪里来的这个故事,我们用 WPF 为客户构建了一个价值 2000 万美元的应用程序,包括自动化和视频监控,具有一个非常负载的界面,分为 4 个屏幕,并有 10 个集群服务器,如果您有性能问题,请检查您的代码。
  • 我不是在谈论加载的界面,我不是在谈论必须操纵数千个 StreamGeometry 对象。您的业​​务利润完全无关紧要。
  • @Szesan 我在这方面工作。可能对我有帮助。谢谢
猜你喜欢
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 2014-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
相关资源
最近更新 更多