首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何处理BitmapImage缓存?

如何处理BitmapImage缓存?
EN

Stack Overflow用户
提问于 2015-02-06 11:10:48
回答 1查看 10.1K关注 0票数 7

我正面临着记忆泄漏的问题。泄漏来自这里:

代码语言:javascript
复制
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,但没有清除它。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-06 13:15:59

我找到了答案,here。好像是WPF中的一个bug。

我修改了函数以包括Freeze

代码语言:javascript
复制
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;
}

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

代码语言:javascript
复制
public void Close()
{
    myImage.Source = null;
    UpdateLayout();
    GC.Collect();
}  

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

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28364439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档