【发布时间】:2017-03-15 14:00:55
【问题描述】:
有一个复杂的App,我尽量简化场景。有一个主机 .exe (.NET),其中包含许多控件(ActiveX、.NET、WPF)。
一个控件基本上是一个带有项目的网格(称为“列表”),当发生新选择时,它会向另一个 WPF 控件(称为“DataView”)发送一条消息。 “DataView”将显示当前选择的“列表”的详细信息。
当 DataView 收到该消息时,它将重新创建它的 ViewModel,并分配给它的 DataContext,因此重新创建它的 View。
它的 View 很复杂(XAML 声明),充满了控件、模板,并且还包含了几个 Image(类型:NonDPIImage,派生自 Image,有一些基本的不重要的变化,只考虑它是 Image),它的 Source 是一个转换器,它创建位图图像。
<Image.Source>
<MultiBinding Converter="{StaticResource ImageConverter}">
...
它工作正常,但我注意到在选择更改后,“DataView”更新变得越来越慢。
我调试了一下,发现经过几次selection的变化,之前的所有View都还在内存中,都在渲染它的内容,所以之前的所有View都调用了ImageConverter,所以越来越慢了。
我尝试分析,这是我在 10 多次选择后看到的。
您会看到之前的 Views 仍在内存中(低优先级问题),以及图像,并且仍在渲染(高优先级问题),这使得应用程序越来越慢。
我对 WPF 不是很熟悉,我是在泄漏后阅读的(主要是不使用 DependencyProperty 或类似的),但是这个控件非常困难,首先我想快速解决,所以防止渲染泄漏的视图,然后再调查内存问题。 (当然两者都是最好的……)
我试过之前把DataContext赋给新的值,把当前的View Image.Source设置为null,这样至少泄露的Image不会自己渲染,但这会导致新的View(!)也丢失了它的 Image.Source,看起来 WPF 正在缓存或共享一些静态数据?
由于我的第一个优先事项是停止“不可见渲染”,在此之后我尝试在创建新的之前将一些模型属性设置为 null(所以它仍然会泄漏,但至少不再渲染),所以当 Converter 将接收创建图像的属性时,将看到它为空,并跳过渲染。
但它的行为很奇怪!
对于泄漏的实例,断点没有在 properties_get 代码中命中,就像 WPF 缓存值一样?
这阻止了我继续走这条路。
任何帮助/想法将不胜感激。
【问题讨论】:
标签: wpf performance memory-leaks render slowdown