如何配置BitmapImage缓存?

How to dispose BitmapImage cache?

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

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

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

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

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

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

我找到了答案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()。否则,它仍然会在记忆中挥之不去。