如何配置BitmapImage缓存? [英] How to dispose BitmapImage cache?
问题描述
我正面临内存泄漏问题.泄漏来自这里:
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屋!