2011-04-26 72 views
23

我有一个WPF应用程序,它很慢。WPF:缓慢的模板实例

它是不是的渲染。首先,渲染非常简单,其次,我用WPF性能工具包来查看 - 没有任何东西。

这是不是在我自己的代码。首先,单元测试工作速度很快,其次,如果我将所有DataTemplates替换为空白,则一切工作都很快。

到目前为止,它看起来像缓慢的部分是模板实例化。也就是说,当你启动应用程序并打开一些复杂的屏幕时,需要很多的时间。并且“很多”我的意思是“很多”。有时可能需要3-5秒 - 例如,当存在一个包含100行的数据网格时。但是,当你转到另一个选项卡,然后返回到同一个屏幕时,它会快速打开(只要它的视图模型保持放置状态)。

这很烦人,不仅因为它很慢,而且因为我对此无能为力。如果我有过一些缓慢控制,我可以,也许,显示一些“开放,请稍候”消息或东西...

此外,当我看一些其他的WPF应用程序(最值得注意的是,ILSpy)尽管数据量很大,但他们似乎工作得相当快。这让我相信我可能做错了什么。但我不知道从哪里开始。

任何想法?任何经典错误?有小费吗?

+0

你想知道和做出有教育的猜测是什么问题。不要怀疑。不要猜测,也不要指望Performance Toolkit告诉你。 [这是如何找出。](http://stackoverflow.com/questions/375913/what-c​​an-i-use-to-profile-c-code-in-linux/378024#378024) – 2011-04-26 13:58:30

+0

@Mike:是,我广泛使用这种原始采样技术,并且在普遍性能下降时帮助我很多。但在这种情况下,我只是没有足够的时间来停止执行,因为性能下降最多只能持续3-5秒。另外,在我设法阻止它的极少数情况下,它总是停留在WPF的内核中。我也追求这个线索(在ILSpy的帮助下),但到目前为止,它看起来很无望。因此,我的问题更多的是与WPF相关的问题。 – 2011-04-26 16:52:05

+0

对。它停在WPF的内核中,但是堆栈上有什么?堆栈中的每一行都负责这段时间。我曾经有人说过“哦,每次我停止它,它都在一些迭代器中,那有什么好处?”答案是*很棒*,现在只需查看堆栈,就会发现问题。如果你猜猜问题是什么,那么它会告诉你,如果你是对的,如果你错了,它会告诉你什么是正确的问题。 – 2011-04-26 20:51:27

回答

1

您是否将您的WPF应用程序作为64位应用程序运行?

然后WPF slow to start on x64 in .NET Framework 4.0可能会有所帮助。

+0

看起来不错,但没有。首先,我实际上运行该应用程序作为一个32位进程(我使用一些本地DLL不存在于64位)。其次,即使我确信所有相关的代码已经被打乱,速度也一样慢。下面是我如何知道这一点:我启动应用程序,创建一个新项目(我有'项目'的这个概念),测试用户界面,并看到它很慢。然后我再次创建一个新项目(不关闭应用程序!)。在这一点上,所有旧模型和视图模型都被扔掉了,并且创建了新模型。然后我再次测试用户界面 - 而且速度又很慢。 – 2011-05-01 18:36:47

5

我exerience来自于WPF思维导图应用NovaMind

几个月前,我们完全重写我们的中间层来解决我们所经历的性能问题的工作。简而言之,创建我们的用户控件似乎是减速的方式。不幸的是,我找不到一个好的方式来描述性能,因为WPF性能套件和商业应用程序(如ANTS Profiler)都不会提供有关此部分WPF过程的任何详细信息。 (当时我问了this question

我们采取了通过反复试验来手动测试我们的应用程序,并删除了部分用户控件,以查看究竟是什么罪魁祸首。

最后,我们通过完全重写我们的控件来解决性能问题。我们也大大减少了视觉树的复杂性。在重写之前,我们最常用的用户控件之一,当用Snoop进行检查时,由61种不同的东西组成,现在只有3种。只要有可能,我们只会根据需要在视觉树中添加内容。 (正如您在XAML中所知道的,即使您将事物设置为Collapsed,也需要先创建它们)。 最后,我们不得不编写自己的富文本渲染控件,因为RichtextBox的内置速度非常慢,RichtextBox的可视化树相当复杂。

我不知道这是否适用于您的情况,但我会建议您调查您的用户控件并查看它们是否复杂。也许你有可以修剪的东西。 低悬的水果将是很难看得见的部分,或者可以用懒惰的方式创建。您可以根据需要在代码后面创建这些部分,而不是将它们放在XAML中。这应该会对你有所帮助。

否则虚拟化是你的朋友,如果可能的话。在我们的情况下,我们不能那么做。在您的数据模板

+0

我刚刚验证了可视化树的大小。大约需要1秒钟的屏幕总共包含850个视频。你的经历是否过度?什么树大小可以接受? – 2011-05-06 17:30:58

1

用户控制,不完全是坏主意,但如果你渴望的性能,那么你应该考虑改用更轻控制。例如,拥有一个UserControl只是托管一个TextBox是非常糟糕的想法,因为UserControl由ContentControl组成,ContentControl主机ContentPresenter和ContentPresenter将托管TextBox,所以如果您注意到您的可视树,它有三个新的UI元素层。减少可视树一定会提高性能。

最有可能,我会建议创建自定义控件这可能是一个完全具有能与你想呈现的数据,你可以在generic.xaml自己的自定义模板几个依赖属性一个新的控制。其次,您可以简单地从现有控件派生出一个控件,并在generic.xaml中重新定义其默认模板。

这种方法当然会更好,因为您将减少可视化树,从而减少视觉状态管理器的工作。

更改主题或模板将变慢,然后更改托管内容的元素。让元素在其自己的通用资源字典中具有默认模板。

1
  • 建议您升级所有的资源 据他们会去,最好到 的App.xaml
  • 检查是否可以使用静态资源 而不是动态的,静态的 都快得多
  • 如果可能的话,尽量在你的虚拟机使用depedency 性能,特别是如果 你对他们有很多在一次或者 他们有很多的特性。这将使wpf不必做一堆反思。
+0

1)资源已全部在app.xaml中。 2)我从不使用DynamicResource。只有静态。3)不能这样做:首先,依赖项属性需要线程关联,其次,它们实际上比POCO属性慢很多。有关详细信息,请参阅此文章:http://www.markusegger.com/blog/development.aspx?messageid=3dfccfc5-1a30-4af1-a924-da22f3ff6057 – 2011-05-05 17:08:25

+0

oppinions在#3上有所不同,因为数据绑定依赖属性的速度更快。 http://msdn.microsoft.com/en-us/library/bb613546.aspx至于线程关联。是的,这是真的,但你绑定到的控件无论如何都是线程的亲和力,所以你仍然必须处理那个..哦,好吧,只是把它扔出去:) – aL3891 2011-05-05 18:46:39

+0

另一个例子,也见相关文章链接http:// blog .resique-du-net.com/index.php?post/2010/02/24/DependencyProperties-or-INotifyPropertyChanged – aL3891 2011-05-05 21:55:22

1

你提到你正在使用一个DataGrid有,比方说,100行。你的性能问题的一个可能的罪魁祸首是,你使用的任何数据网格都不是在做虚拟化,所以你的视觉树是巨大的。

通常情况下,WPF屏幕中的启动时间很长,指向一个很大的可视化树。

我不知道,如果你正在使用每行一个DataTemplate,或结合列,或者说一些第三方的网络 - 但可以说你有8列与控制。根据你的网格/验证/等,这可能是一个20-60个项目每行的可视化树。如果你有一个组合框,那么下拉菜单中的每个项目也可以被创建。

为了解决这个问题只需要看完信息,并采取措施,当您去:

  1. 使用虚拟化控制尽可能多的。这意味着使用内部列表控件一个virtualizingstackpanel,并确保您的第三方控件做的一样好(很多股票的WPF控件现在做的默认)
  2. 不要过度使用用户控件,复合控件等添加深度增加了时间和投入数据模板或其他重复区域中的额外视觉树深度加起来很快。
  3. 如果一切都失败,显示简单的屏幕,并通过代码添加控件来提高感知性能
1

这听起来很相似,我有一个问题。我在此发布修复程序:WPF UI Automation issue。只是为了搜索者的利益发布,因为它需要很长时间才能解决。