【问题标题】:How to dispose BitmapImage cache?如何处理 BitmapImage 缓存?
【发布时间】:2015-04-06 12:24:07
【问题描述】:

我遇到了内存泄漏问题。泄漏来自这里:

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

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

当我关闭ScatterViewItem 时出现问题,这反过来又关闭了Image。但是,缓存的内存没有被清除。所以经过多次循环,内存消耗是相当大的。

我尝试在Unloaded函数中设置image.Source=null,但没有清除。

卸载时如何正确清空内存?

【问题讨论】:

标签: c# wpf


【解决方案1】:

我找到了答案here。似乎这是 WPF 中的一个错误。

我修改了函数以包含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 之前调用:

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

因为myImage 托管在ScatterViewItem 中,所以必须在关闭父级之前调用GC.Collect()。否则,它仍然会留在记忆中。

【讨论】:

    猜你喜欢
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 2019-10-10
    • 2012-06-01
    • 2020-10-12
    • 2013-11-26
    相关资源
    最近更新 更多