【问题标题】:Performance issue when hosting a WPF form in a native C++ application在本机 C++ 应用程序中托管 WPF 表单时的性能问题
【发布时间】:2013-01-22 19:45:17
【问题描述】:

我的 WPF 窗口在托管在 WPF 应用程序中时运行良好,但是当我从本机 C++ 应用程序中加载它时,渲染需要很长时间,并且 UI 线程会阻塞直到它完成。

我窗口上的主要问题是一系列项目控件,用于显示 9 x 12 的图标网格,这些图标代表我系统中组件的状态。

整个项目控件的初始渲染最多需要 14 秒。 (在 WPF 应用程序中运行时,这几乎是即时的)

每一行都有一个文本标题,单击该标题时会显示每个状态图标的小数据摘要(最大值、最小值、平均值、标准差)。单击此标题最多可能需要 4 秒来呈现摘要,但在我的 WPF 应用程序中是即时的。

是否有任何已知的技巧可以使 WPF 在本机应用程序中正常运行?

[编辑]

我刚刚尝试使用以下代码从大型 .NET Windows 窗体应用程序启动它:

    public bool? ShowWpfDialog(System.Windows.Window window, Form owner)
    {
        var helper = new System.Windows.Interop.WindowInteropHelper(window)
                         {Owner = (owner == null) ? IntPtr.Zero : owner.Handle};
        return window.ShowDialog();
    }

我遇到了与从本机应用程序运行时相同的性能问题。 (.net 应用程序也运行本机代码。)

[编辑]

当我不使用 WindowInteropHelper 时,代码会正常执行:

    public bool? ShowWpfDialog(System.Windows.Window window, Form owner)
    {
        //var helper = new System.Windows.Interop.WindowInteropHelper(window)
        //                 {Owner = (owner == null) ? IntPtr.Zero : owner.Handle};
        return window.ShowDialog();
    }

WindowInteropHelper 做了什么会导致性能问题?

[编辑]

当我使用 WindowInteropHelper 与所有者一起加载资源时,解决资源的方式是否存在问题?

【问题讨论】:

  • 你在调试器中运行/计时吗?
  • 时间基于运行发布版本时的观察
  • 你是在VS托管进程中运行,还是在独立/外部VS运行?
  • 那是 C++/CLR 吗?我会指出互操作/线程配置的方向。线程模型可能是问题所在。您是否尝试过在 Visual Studio 中进行分析器调试以查看挂在哪里? 14 秒是一个非常多的时间 - 这应该是显而易见的。
  • 许多性能问题可能与 Windows 主题、视觉样式和您运行的 Windows 版本有关。本机应用程序可以使用与内置 .NET/WPF 不同的参数启动。我建议阅读这些读数以获得想法:blogs.msdn.com/b/visualstudio/archive/2010/03/02/… 并最终使用 WPF 性能套件工具:msdn.microsoft.com/en-us/library/vstudio/…

标签: c++ wpf performance native


【解决方案1】:

WindowInteropHelper 的文档表明您应该将 HELPER 的句柄设置为您的 c++ 句柄

WindowInteropHelper wih = new WindowInteropHelper(myDialog);
wih.Owner = ownerHwnd;
myDialog.ShowDialog();

但你似乎在做相反的事情。

【讨论】:

    【解决方案2】:

    您在帖子中没有提到HwndSourceHwndHost,它们是本机代码之间互操作的受支持方式(在Win32 中托管WPF 或反之亦然)。 WindowsInteropHelper 并非旨在支持完整的互操作场景,它的唯一用途是基本上获取 WPF Window 的句柄。

    These 是一系列很棒的文章,我建议您仔细阅读它们,因为除非范围非常有限,否则您想做的事情不会是微不足道的。

    【讨论】:

      【解决方案3】:

      您可以尝试通过NGEN 创建和使用您的 .NET 程序集的本机图像,这将显着加快速度,尽管我不知道您的情况会有多大差异......至少它应该减少加载次

      【讨论】:

      • 如果我找不到其他解决方案,我会试试这个 - 我不知道我是否可以在我们的集成构建环境中这样做
      • 没有。 14 秒太疯狂了,而且他说它在 wpf 应用程序中运行得很快,而且 99% 没有被修改——指向错误的方向。即使开始运行时也不应该是 14 秒。
      • 开始运行时间不是 14 秒 - 窗口快速打开,然后控件 - 响应从服务获取的数据 - 最多需要 14 秒来呈现。仅当窗口使用 WindowInteropHelper 附加了所有者时才执行此操作,如果我简化模板,它们的渲染速度会更快,这让我相信这可能与更大应用程序中的资源解析有关。
      • 实际上声称 .NET 是“不成熟的”(不管那是什么意思)只是证明严重缺乏知识。 .NET 应用程序总是“生成”,这是使用 .NET 的主要原因 - 编译的字节码将在运行时被翻译成本机代码,这是在内存中完成的(“生成”)并立即在使用生成的代码之前。 NGEN 只是一个加速这个过程的工具,它预编译了一切。也许停止假设事情......只是一个建议
      • 请停止使用“ngen”来表示 JIT 编译,确实总是这样做。 Ngen 特指提前运行编译并将生成的本机代码存储在磁盘上。说 .NET 总是 ngens 是完全错误的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      相关资源
      最近更新 更多