如何配置BitmapImage缓存? [英] How to dispose BitmapImage cache?

查看:44
本文介绍了如何配置BitmapImage缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正面临内存泄漏问题.泄漏来自这里:

I'm facing a memory leak issue. The leak comes from here:

public static BitmapSource BitmapImageFromFile(string filepath)
{
    BitmapImage bi = new BitmapImage();

    bi.BeginInit();
    bi.CacheOption = BitmapCacheOption.OnLoad; //here
    bi.CreateOptions = BitmapCreateOptions.IgnoreImageCache; //and here
    bi.UriSource = new Uri(filepath, UriKind.RelativeOrAbsolute);
    bi.EndInit();

    return bi;
}

我有一个 ScatterViewItem ,其中包含一个 Image ,其来源是此函数的 BitmapImage .

I have a ScatterViewItem, which contains an Image, and the source is the BitmapImage of this function.

实际情况比这复杂得多,因此我不能简单地将Image放入其中.我也不能使用默认的加载选项,因为图像文件可能会被删除,因此在删除过程中访问该文件时会遇到一些权限问题.

The actual thing is a lot more complex than this, so I can't simply put an Image into it. I also can't use the default load options, as the image file might be deleted and hence will face some permission issue accessing the file during deletion.

当我关闭 ScatterViewItem ,这又关闭了 Image 时,就会出现问题.但是,缓存的内存不会清除.因此,经过多个周期后,内存消耗非常大.

The problem occurs when I close the ScatterViewItem, which in turn closes the Image. However, the cached memory isnt cleared. So after many cycles, the memory consumption is pretty big.

我尝试在 Unloaded 函数期间设置 image.Source = null ,但是并没有清除它.

I tried setting image.Source=null during the Unloaded function, but it didn't clear it.

如何在卸载过程中正确清除内存?

How do I clear the memory correctly during unloading?

推荐答案

我找到了答案这里.似乎是WPF中的错误.

I found the answer here. Seems like it's a bug in WPF.

我修改了此功能,使其包含 Freeze :

I modified the function to include Freeze:

public static BitmapSource BitmapImageFromFile(string filepath)
{
    var bi = new BitmapImage();

    using (var fs = new FileStream(filepath, FileMode.Open))
    {
        bi.BeginInit();                
        bi.StreamSource = fs;                
        bi.CacheOption = BitmapCacheOption.OnLoad;
        bi.EndInit();
    }

    bi.Freeze(); //Important to freeze it, otherwise it will still have minor leaks

    return bi;
}

我还创建了自己的Close函数,该函数将在我关闭 ScatterViewItem 之前被调用:

I also create my own Close function, which will be called before I close the ScatterViewItem:

public void Close()
{
    myImage.Source = null;
    UpdateLayout();
    GC.Collect();
}  

由于 myImage 托管在 ScatterViewItem 中,因此必须在关闭父级之前调用 GC.Collect().否则,它仍会在内存中徘徊.

Because myImage is hosted in a ScatterViewItem, GC.Collect() must be called before the parent is closed. Otherwise, it will still linger in memory.

这篇关于如何配置BitmapImage缓存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆