如何配置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()
。否则,它仍然会在记忆中挥之不去。
我遇到内存泄漏问题。泄漏来自这里:
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()
。否则,它仍然会在记忆中挥之不去。