我正面临内存泄漏问题。泄漏来自这里:
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}},但它没有清除它。
如何在卸载过程中正确清除内存?
答案 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()
。否则,它仍将留在内存中。