如何配置BitmapImage缓存?

时间:2015-02-06 11:10:48

标签: c# wpf

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

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会关闭image.Source=null。但是,缓存的内存未清除。因此,经过多次循环后,内存消耗量非常大。

我尝试在Unloaded功能期间设置{{1}},但它没有清除它。

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

1 个答案:

答案 0 :(得分:5)

我找到了答案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()。否则,它仍将留在内存中。