【问题标题】:WPF InitializeComponent performance problemsWPF InitializeComponent 性能问题
【发布时间】:2010-11-24 03:06:32
【问题描述】:

我有一个 WPF 应用程序 (.NET 4),它有一个主窗口,在该主窗口内显示了许多较小的 UserControls。用户执行的各种操作会导致显示的UserControls 被具有不同数据的不同其他控件替换。

但是,在切换这些控件时,我遇到了性能问题。 WPF 调度程序线程在加载控件时进入 100% CPU。在较旧的机器上,或具有大量控件的情况下,这可能会导致应用程序似乎锁定长达 30 秒!

分析表明,几乎所有这些 CPU 时间都用于调用所有不同 UserControls 的各种 InitializeComponent 方法 - 没有一个控件似乎比其他任何控件都差得多,它们似乎都在 0.2 和 0.5 之间秒(在我的具有快速处理器和良好显卡的开发机器上)。

据我所知,InitializeComponent 是 WPF 实际将编译后的 xaml 加载到内存中的位置。

我不知道在这里做什么。我想在后台线程上预初始化,但所有 WPF 控件都必须在调度程序线程上创建和使用,所以我认为这是不可能的。

否则,我唯一的选择似乎是删除我所有的 xaml??

任何帮助将不胜感激

【问题讨论】:

  • 在不了解您的应用程序的更多信息(具体细节 + 代码)的情况下,我只能想象您要么拥有大量的用户控件 (+50) 和/或非常繁重的数据绑定。所以唯一的答案是重新设计你的应用程序逻辑。您还必须了解的是,当涉及大量控件/数据时,WPF 绝对是垃圾,因为它严重未优化(我想它的框架级别太高了)。也许为您的应用程序尝试 WinForms(更好一点)或用原生 c++/directx 编写所有内容(a'la Photoshop,AutoCAD 风格)
  • jeremiahmorrill.wordpress.com/2011/02/14/… - 我猜控件正在加载,渲染生成并可能被缓存。它确实提到了您可能想尝试的 PIX(一种 WPF 性能工具)。

标签: c# wpf performance


【解决方案1】:

重新审视这一点 - 我们在屏幕上确实有许多复杂的控件,但我们不能仅仅摆脱它们来保持 WPF 的快乐!

进一步的分析实验表明,使用自定义控件(基本上只是直接从 Control 派生的 C# 类并在 Generic.xaml 主题文件中定义 UI 似乎只会导致加载和解析 XAML 一次。此后,每个控件只应用预先存在的主题。

自定义控件比 UserControls 更难使用,但这似乎对我们的加载性能有很大帮助。

【讨论】:

    【解决方案2】:

    InitializeComponent 方法需要时间,因为它需要将控件插入可视/逻辑树并确保所有绑定、主题、预期资源等。

    我唯一的建议是 - 是否可以从一开始就初始化所有潜在控件,然后在需要时使用 Visibility 属性显示/隐藏它们?

    您可以使用 Freezable 来缓存某些 UI,但如果它们是用户控件,那么您很可能希望您的用户与它们进行交互。

    【讨论】:

    • 感谢您的回答,但我们最初是预先加载所有控件,然后只显示我们需要的控件。然后在第一次显示表单时出现了巨大的延迟(在较慢的机器上超过一分钟),这比当前的行为更糟​​糕的用户体验:-(
    【解决方案3】:

    为了记录,我有一个加载时间约为 1500 ~ 2000 毫秒的窗口,问题是 图标

    我使用了一个将 SVG 转换为 XAML DrawingImage 元素的工具,以及一个带有大型资源字典的用户控件,其中每个使用的图标都有一个绘图图像

    InitializeComponent 非常慢,因为它必须解析包含图像所有矢量数据的大型 XAML 文件

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多