在本机c++应用程序中托管WPF表单时的性能问题

时间:2022-09-01 19:16:51

I have WPF window which runs fine when hosted in a WPF application but when I load it from within my native C++ application it takes a very long time to render and the UI Thread blocks until it completes.

我有WPF窗口,它在WPF应用程序中运行良好,但是当我从本机c++应用程序中加载它时,它需要很长时间才能呈现,UI线程会阻塞,直到它完成。

The main offender on my window is an series of items controls used to display a 9 by 12 grid of icons which represent states of components within my system.

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

The whole items control takes up to 14 seconds for its initial render. (This is almost instant when running in a WPF app)

整个项目控件的初始渲染时间为14秒。(在WPF应用程序中运行时几乎是瞬间完成的)

Each line has a text header that when clicked displays a small summary of data (max, min, mean, std dev) for each of the status icons. clicking this header can take up to 4 seconds to render the summary but is instant in my WPF app.

每一行都有一个文本头,点击时显示每个状态图标的小汇总数据(max, min, mean, std dev)。单击此标题可以花费4秒的时间来呈现摘要,但在我的WPF应用程序中是即时的。

Are there any known tricks for making WPF perform nicely within a native application?

在本地应用程序中,有什么已知的方法可以使WPF执行得很好吗?

[Edit]

(编辑)

I have just tried launching it from a large .NET windows forms application using the following code:

我刚刚尝试从一个大型的。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();
    }

I have the same performance issues as when running from the native app. (the .net app also runs native code.)

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

[Edit]

(编辑)

When I don't use the WindowInteropHelper the code performs properly:

当我不使用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();
    }

What is the WindowInteropHelper doing that would cause a performance issue?

什么是WindowInteropHelper会导致性能问题?

[Edit]

(编辑)

Could there be an issue with the way resources are resolved when I load it with an owner using the WindowInteropHelper?

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

3 个解决方案

#1


1  

The docs for WindowInteropHelper indicate that you should set the HELPER'S handle to your c++ handle

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

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

But you seem to be doing the opposite.

但你似乎在做相反的事。

#2


1  

Nowhere in your post do you mention HwndSource or HwndHost which are the supported means of interoping between native code (either hosting WPF in Win32 or visa versa). WindowsInteropHelper is not intended to support full blown interop scenarios, it's only use is to basically get the Handle of a WPF Window.

在你的博文中,你没有提到HwndSource或HwndHost,它们是原生代码之间相互作用的支持手段(在Win32中托管WPF,反之亦然)。WindowsInteropHelper并不打算支持完整的互操作场景,它只用于获得WPF窗口的句柄。

These are a great series of articles and I recommend looking through them, because what you want to do is not going to be trivial unless it's a very limited scope.

这是一组很棒的文章,我建议你仔细阅读它们,因为你想要做的事情不是微不足道的,除非它是一个非常有限的范围。

#3


0  

you could try creating and using native images of your .NET-assembly via NGEN, this will significantly speed things up although i dont know how big the difference will be in your case ... at least it should reduce loading times

您可以尝试通过NGEN创建和使用. net程序集的本机映像,这将大大加快速度,尽管我不知道您的情况会有多大的不同……至少可以减少加载时间

#1


1  

The docs for WindowInteropHelper indicate that you should set the HELPER'S handle to your c++ handle

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

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

But you seem to be doing the opposite.

但你似乎在做相反的事。

#2


1  

Nowhere in your post do you mention HwndSource or HwndHost which are the supported means of interoping between native code (either hosting WPF in Win32 or visa versa). WindowsInteropHelper is not intended to support full blown interop scenarios, it's only use is to basically get the Handle of a WPF Window.

在你的博文中,你没有提到HwndSource或HwndHost,它们是原生代码之间相互作用的支持手段(在Win32中托管WPF,反之亦然)。WindowsInteropHelper并不打算支持完整的互操作场景,它只用于获得WPF窗口的句柄。

These are a great series of articles and I recommend looking through them, because what you want to do is not going to be trivial unless it's a very limited scope.

这是一组很棒的文章,我建议你仔细阅读它们,因为你想要做的事情不是微不足道的,除非它是一个非常有限的范围。

#3


0  

you could try creating and using native images of your .NET-assembly via NGEN, this will significantly speed things up although i dont know how big the difference will be in your case ... at least it should reduce loading times

您可以尝试通过NGEN创建和使用. net程序集的本机映像,这将大大加快速度,尽管我不知道您的情况会有多大的不同……至少可以减少加载时间