Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/85.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
Memory leaks WPF-带有不透明掩码/可视笔刷的边框:内存泄漏_Memory Leaks_Binding_Visualbrush_Opacitymask - Fatal编程技术网

Memory leaks WPF-带有不透明掩码/可视笔刷的边框:内存泄漏

Memory leaks WPF-带有不透明掩码/可视笔刷的边框:内存泄漏,memory-leaks,binding,visualbrush,opacitymask,Memory Leaks,Binding,Visualbrush,Opacitymask,关于我的应用程序的简要说明: 我正在开发的应用程序就是这样一个贺卡设计师。想象一下,其中有一个背景图像和无限数量的“层”(特别是图片),这些层位于背景之上,可以移动、调整大小、前后移动,等等 也可以在这些层上应用特定的形状,如星形、椭圆形等。。卡片制作完成后,可以将其保存到jpeg文件中 问题 一切正常,但我检测到,当一个形状应用于一个层时,会产生内存泄漏 以下是每层用户控件的代码: 参数“MyMask.Data”是一个XAML路径(即我正在应用的形状),我从包含不同形状的文本文件中手动加载该路

关于我的应用程序的简要说明:

我正在开发的应用程序就是这样一个贺卡设计师。想象一下,其中有一个背景图像和无限数量的“层”(特别是图片),这些层位于背景之上,可以移动、调整大小、前后移动,等等

也可以在这些层上应用特定的形状,如星形、椭圆形等。。卡片制作完成后,可以将其保存到jpeg文件中

问题

一切正常,但我检测到,当一个形状应用于一个层时,会产生内存泄漏

以下是每层用户控件的代码:

参数“MyMask.Data”是一个XAML路径(即我正在应用的形状),我从包含不同形状的文本文件中手动加载该路径

因此,原则是,如果我将边界命名为*im\u the \u problem*,则不会释放内存。如果我评论*我就是问题所在*(因此我将只使用没有形状的矩形层/图片),一切都像一个魅力,没有内存泄漏

问题应该在OpacityMask+VisualBrush中

我做错什么了吗? 还是存在已知的问题?有没有一种方法可以以不同的方式进行相同的操作(将形状应用于图片…)


谢谢

您可以尝试将MyMask.Data绑定到实际的Path.Data,并将Path.Fill设置为从图像创建的ImageBrush?

您需要冻结VisualBrush;)

我在
DataGrid
的列模板中遇到了这个问题,当时我将
(作为静态资源)使用到
VisualBrush
(也是一个静态资源)中,并将其用作
矩形的
不透明掩码。每当重新加载DataGrid时,
矩形
就不会释放对
OpacityMask
VisualBrush
引用,我使用内存探查器工具显示所有
VisualBrush
对象都在使用大量内存

我不明白为什么会发生这种情况,也不知道是怎么发生的,但我很高兴我不是一个人(即使我在6.5年后也遇到了同样的问题……)

我的XAML是这样的:

<DataGrid.Resources>

    <Canvas x:Key="icon" ...>
        <Path ... />
    </Canvas>

    <VisualBrush x:Key="iconBrush" Stretch="Uniform" Visual="{StaticResource icon}" />

</DataGrid.Resources>

<DataGrid.Columns>

    <DataGridTemplateColumn>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Rectangle
                    Fill="{Binding Foreground, ElementName=myDataGrid}"
                    Width="14"
                    Height="14"
                    Margin="4"
                    Visibility="{Binding IconVisibility}"
                    OpacityMask="{StaticResource iconBrush}"
                />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>

    ...

</DataGrid.Columns>
这解决了问题!我仍然不知道为什么——我想知道这是否是WPF中的一个bug

另一方面,我开始意识到使用
VisualBrush
有点过分,因为我只渲染一个简单的
Path
-
VisualBrush
非常昂贵,因为它可以渲染整个WPF视图-我还从其他文档中了解到,
Path
本身对于渲染简单的形状来说是不必要的,因为它本身是一个完整的图形
UIElement
FrameworkElement
——它们是“较重”的类型

我更改了代码,将路径存储在加载到
DrawingBrush
GeometryDrawing
静态资源中的
PathGeometry
值中:

<GeometryDrawing x:Key="iconDrawing" Brush="Black" Geometry="..." /> 

<Rectangle
    Fill="{Binding Foreground, ElementName=myDataGrid}"
    Width="14"
    Height="14"
    Margin="4"
    Visibility="{Binding IconVisibility}"
    OpacityMask="{StaticResource iconBrush}"
>
    <DrawingBrush Stretch="Uniform" Drawing="{StaticResource iconDrawing}" />
</Rectangle>

这样做还降低了内存使用率,并有望降低性能

在您的项目中,我看到您没有将路径信息用作资源,但同样的技术也适用:将路径加载到
PathGeometry
(或者更确切地说,
StreamGeometry
对象中,该对象速度更快,适用于不可变的几何体),并将其设置为
DrawingBrush
绘图

<DataGrid.Resources>

    <Canvas x:Key="icon" ...>
        <Path ... />
    </Canvas>

    <VisualBrush x:Key="iconBrush" Stretch="Uniform" Visual="{StaticResource icon}" />

</DataGrid.Resources>

<DataGrid.Columns>

    <DataGridTemplateColumn>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Rectangle
                    Fill="{Binding Foreground, ElementName=myDataGrid}"
                    Width="14"
                    Height="14"
                    Margin="4"
                    Visibility="{Binding IconVisibility}"
                    OpacityMask="{StaticResource iconBrush}"
                />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>

    ...

</DataGrid.Columns>
    <DataGridTemplateColumn>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Rectangle
                    Fill="{Binding Foreground, ElementName=myDataGrid}"
                    Width="14"
                    Height="14"
                    Margin="4"
                    Visibility="{Binding IconVisibility}"
                >
                    <VisualBrush Stretch="Uniform" Visual="{StaticResource iconBrush}" />
                </Rectangle>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
<GeometryDrawing x:Key="iconDrawing" Brush="Black" Geometry="..." /> 

<Rectangle
    Fill="{Binding Foreground, ElementName=myDataGrid}"
    Width="14"
    Height="14"
    Margin="4"
    Visibility="{Binding IconVisibility}"
    OpacityMask="{StaticResource iconBrush}"
>
    <DrawingBrush Stretch="Uniform" Drawing="{StaticResource iconDrawing}" />
</Rectangle>