Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net WPF内存泄漏_.net_Wpf_Performance_Memory Leaks - Fatal编程技术网

.net WPF内存泄漏

.net WPF内存泄漏,.net,wpf,performance,memory-leaks,.net,Wpf,Performance,Memory Leaks,我有一个我自己没有创建的WPF表单,所以我不太擅长WPF。但它的泄漏非常严重,高达400 MB,关闭表单也无济于事 问题在于我的应用程序一次加载所有图片。我只想加载那些目前可见的。它大约有300张图片,它们有点大,所以我的WPF表单在加载它们时会遇到麻烦 我有一个带有我自己类型的DataTemplate,它有一个属性缩略图。模板中的代码如下所示: <Image Source="{Binding Path=Thumbnail}" Stretch="Fill"/>

我有一个我自己没有创建的WPF表单,所以我不太擅长WPF。但它的泄漏非常严重,高达400 MB,关闭表单也无济于事

问题在于我的应用程序一次加载所有图片。我只想加载那些目前可见的。它大约有300张图片,它们有点大,所以我的WPF表单在加载它们时会遇到麻烦

我有一个带有我自己类型的
DataTemplate
,它有一个属性
缩略图
。模板中的代码如下所示:

            <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>


仅凭代码片段很难缩小问题的范围。如果还没有,您可能会想要。

所描述的“ElementFlow”控件是否相同?控件似乎是,所以我不希望它访问不可见项的缩略图属性

您如何对公开“缩略图”属性的数据结构进行建模?您能将其设置为属性需求在第一次访问时加载缩略图吗?也许通过一个后备缓存(在一段时间内保持缩略图加载)来实现这一点可以解决这个问题

编辑


我可能已经假设了一些我不应该做的事情。在阅读我链接的第二篇文章的评论时,我现在认为可能是ElementFlow控件的公开版本实际上没有实现虚拟化。也许您可以记录对“缩略图”属性的访问,并确定是否针对不可见的元素访问该属性。

当您试图在.NET应用程序中查找内存泄漏时,首先要查看的是订阅事件的对象(WPF与否)

如果对象X正在侦听由对象Y引发的事件,则Y将保留对X的引用。无论您实现了何种虚拟化(或处置)方法,如果X没有取消订阅Y的事件,X将和Y一样留在对象图中,并且永远不会最终确定和垃圾回收。(即使它实现了
IDisposable
,并且您显式地对其调用
Dispose

当你说“关闭表单没有帮助”时,这让我倍感怀疑:我希望有人在
窗口
对象上实现了一个object属性,并且该对象订阅了某种事件。因此关闭窗口,但它仍然存在于对象图中,因为它的一个属性正在被引用

(让您了解这可能有多隐蔽:WinForms
ToolStrip
控件在Windows主题更改事件可见时会订阅这些事件。这很好,因为更改计算机的主题会自动反映在正在运行的应用程序的UI中。如果您取消引用
ToolStrip 如果不首先将
Visible
设置为false,它将继续接收主题更改事件,直到应用程序终止。)


内存分析器可以帮助实现这一点-这就是我发现我的应用程序内存中有数千个
ToolStrip
对象的原因,尽管我认为这些对象都已被销毁。

谢谢。我检查并验证了缩略图属性的检索次数与列表中的项目数相同。是的,这就是我使用的控件我正在使用:)。听起来他发现了同样的事情。实施虚拟化有多难…?:)+1:我公司的WPF应用程序每次生成新页面时都会泄漏兆字节的内存,我们都认为这是WPF的错误。突然打开探查器,发现每个页面都连接到静态事件处理程序,但从未取消连接,从而导致灾难性(且易于修复)泄漏。