我有一个WPF表单,不是我自己创建的,所以我不太擅长WPF。它泄漏很严重,高达400MB,关闭表单也无济于事。
问题出在我的应用程序一次加载所有图片。我只想加载那些目前可见的。它大约有300张图片,它们有点大,所以我的WPF-form无法加载所有图片。
我有一个自己类型的DataTemplate,它有一个Thumbnail属性。模板中的代码如下:
<Image Source="{Binding Path=Thumbnail}" Stretch="Fill"/>然后我有一个网格,它有一个控件,上面的模板作为源。此控件的代码如下所示。请向我提供关于如何优化代码的提示,也许可以获得唯一可见的代码,并且同时加载那么多的控件?
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Controls:ElementFlow">
<Grid Background="{TemplateBinding Background}">
<Canvas x:Name="PART_HiddenPanel"
IsItemsHost="True"
Visibility="Hidden" />
<Viewport3D x:Name="PART_Viewport">
<!-- Camera -->
<Viewport3D.Camera>
<PerspectiveCamera FieldOfView="60"
Position="0,1,4"
LookDirection="0,-1,-4"
UpDirection="0,1,0" />
</Viewport3D.Camera>
<ContainerUIElement3D x:Name="PART_ModelContainer" />
<ModelVisual3D>
<ModelVisual3D.Content>
<AmbientLight Color="White" />
</ModelVisual3D.Content>
</ModelVisual3D>
<Viewport2DVisual3D
RenderOptions.CachingHint="Cache"
RenderOptions.CacheInvalidationThresholdMaximum="2"
RenderOptions.CacheInvalidationThresholdMinimum="0.5"/>
</Viewport3D>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>发布于 2010-05-19 04:59:19
“ElementFlow”控件和here描述的是同一个控件吗?控件似乎是already using virtualization的,所以我不希望它访问不可见项的缩略图属性。
你是如何对暴露“缩略图”属性的数据结构建模的呢?您是否可以将其设置为属性在第一次访问时按需加载缩略图?也许使用一个后备缓存(它可以在一段时间内加载缩略图)来实现这一点可以解决这个问题。
编辑
我可能假设了一些我不应该做的事情。在阅读我链接的第二篇文章的评论时,我现在认为可能是ElementFlow控件的公开版本实际上并没有实现虚拟化。也许你可以记录对“缩略图”属性的访问,并确定不可见元素是否可以访问该属性。
发布于 2010-05-19 08:48:36
当您试图查找.NET应用程序中的内存泄漏时,首先要查看的是订阅事件的对象。
如果对象X正在侦听由对象Y引发的事件,则Y持有对X的引用。无论您实现什么虚拟化(或处置)方法,如果X不取消订阅Y的事件,那么X将像Y一样一直留在对象图中,并且永远不会被完成和垃圾回收。(即使它实现了IDisposable,并且您显式地对其调用了Dispose。)
当您说“关闭窗体无济于事”时,这让我更加怀疑:我认为有人已经在Window对象上实现了一个对象属性,并且该对象已经订阅了某种事件。因此,您关闭了窗口,但它仍然存在于对象图中,因为它的一个属性正在被引用。
(为了让您了解这可能有多隐蔽:在主题更改事件变得可见时订阅WinForms ToolStrip控件。这很棒,因为更改计算机的主题会自动反映在正在运行的应用程序的UI中。这不是很好,因为如果您在没有首先将Visible设置为false的情况下取消引用ToolStrip,它将继续接收主题更改事件,直到应用程序终止。)
内存分析器可以帮助解决这个问题--这就是为什么我发现我的应用程序在内存中有数以千计的ToolStrip对象,尽管我认为它们都已经被销毁了。
发布于 2010-05-19 04:48:01
仅仅使用您的代码片段很难缩小问题的范围。如果您还没有使用Visual Profiler,那么您可能想要这样做。
https://stackoverflow.com/questions/2860965
复制相似问题