我有一个WPF应用程序,而且速度很慢。
不渲染。首先,渲染非常简单,其次,我使用WPF Performance Toolkit查看它 - 没有。
我自己的代码中不。首先,单元测试工作很快,其次,如果我用空白替换所有DataTemplates,一切都很快。
到目前为止,看起来缓慢的部分是模板实例化。也就是说,当你启动应用程序并打开一些复杂的屏幕时,它需要很多的时间。并且通过“很多”我的意思是“很多”。有时可能长达3-5秒 - 例如,当有一个包含100行的数据网格时。但是当你转到另一个标签,然后回到同一个屏幕时,它会快速打开(只要它的视图模型保持不变)。
这非常烦人,不仅因为它很慢,而且因为我无能为力。如果我对缓慢有一些控制,我可能会显示一些“打开,请等待”的消息或其他...
此外,当我查看其他一些WPF应用程序(最值得注意的是ILSpy)时,尽管数据量很大,但它们似乎工作得相当快。这让我相信我可能做错了什么。但我不知道从哪里开始。
有什么想法吗?任何经典错误?有什么提示吗?
答案 0 :(得分:5)
我的经验来自于使用WPF思维导图应用程序NovaMind
几个月前,我们完全重写了我们的中间层,以解决我们遇到的性能问题。简而言之,创建用户控件似乎是放慢速度的方法。遗憾的是,由于WPF Performance Suite和ANTS Profiler等商业应用程序都没有为WPF流程的这一部分提供任何详细信息,因此无法找到一种很好的方式来分析性能。 (当时我问过this question)
我们通过反复试验手动测试我们的应用程序,并删除了部分用户控件,以确定究竟是什么罪魁祸首。
最后,我们通过完全重写控件解决了性能问题。我们还大大降低了视觉树的复杂性。在重写之前,我们最常用的用户控件之一,在使用Snoop进行检查时,由61个不同的东西组成,现在只有3个。只要有可能,我们只会根据需要向可视化树添加内容。 (正如您在XAML中所知,即使您将事物设置为Collapsed,也需要先创建它们)。 最后,我们被迫编写自己的富文本渲染控件,因为内置的RichtextBox非常慢,RichtextBox的可视树非常复杂。
我不知道这是否适用于您的情况,但我建议您调查用户控件并查看它们是否复杂。也许你有可以修剪的东西。 低悬的水果将是很少可见的部分,或者可以以懒惰的方式创建。您可以在必要时从代码后面创建这些部分,而不是在XAML中使用它们。这应该会对你有所帮助。
如果可能的话,虚拟化就是你的朋友。在我们的案例中,我们不幸地不能这样做。
答案 1 :(得分:2)
这听起来类似于我遇到的问题。我在这里发布了修复程序:WPF UI Automation issue。只是为搜索者的利益发布,因为需要很长时间才能解决。
关于仅链接回答的评论,以下是该帖子的关键:
我做了以下事情:
可能只需要3号,但它有效。只是发布在这里,所以人们不会失去我在内存分析器等中丢失的日子。
答案 2 :(得分:1)
数据模板中的用户控制并不是一个坏主意,但如果你渴望性能,那么你应该考虑切换到更轻的控制。例如,让UserControl只托管TextBox是个坏主意,因为UserControl由ContentControl组成,ContentControl主机ContentPresenter和ContentPresenter将托管TextBox,所以如果你注意到你的Visual Tree,它有三个新的UI元素层。减少Visual Tree肯定会提高性能。
我很可能会建议创建自定义控件,它可能是一个完全新的控件,具有很少的依赖属性,可以与您想要呈现的数据相关,并且您可以在generic.xaml中拥有自己的自定义模板。其次,您只需从现有控件派生控件,并在generic.xaml中重新定义其默认模板。
这种方法肯定会更好,因为您将减少Visual Tree,从而减少Visual State Manager的工作。
更改主题或模板的速度会慢于更改承载内容的元素。让元素在其自己的通用资源字典中具有默认模板。
答案 3 :(得分:1)
答案 4 :(得分:1)
您提到您正在使用DataGrid,例如100行。您的性能问题的一个可能的罪魁祸首是,您使用的数据网格不是虚拟化,因此您的可视化树是巨大的。
通常,WPF屏幕中的长启动时间指向大型可视树。
我不确定您是否每行使用一个datatemplate,或者某些绑定列的第三方网格,或者是什么 - 但是假设您有8列控件。根据您的网格/验证/等,这可能是一个20-60项每行的可视化树。如果你有一个组合框,那么下拉列表中的每个项目也可以按行创建。
要解决此问题,只需观察细节,并采取措施: