首先,我上的Window
的Image
控制加载BitmapImage
。 其次,我与Image
控件一起工作,然后关闭Window
。如何在不再需要BitmapImage后释放内存?
我做2-3次一分钟,因为在关闭窗口的图像不卸载回到我的记忆很快填满。
那么如何卸载BitmapImage
从Image.Source
手动控制释放内存?
首先,我上的Window
的Image
控制加载BitmapImage
。 其次,我与Image
控件一起工作,然后关闭Window
。如何在不再需要BitmapImage后释放内存?
我做2-3次一分钟,因为在关闭窗口的图像不卸载回到我的记忆很快填满。
那么如何卸载BitmapImage
从Image.Source
手动控制释放内存?
我相信你正在寻找的解决方案是在http://www.ridgesolutions.ie/index.php/2012/02/03/net-wpf-bitmapimage-file-locking/。就我而言,我试图找到一种在创建文件后删除文件的方法,但似乎是解决这两个问题的方法。
不释放内存:
var bitmap = new BitmapImage(new Uri(imageFilePath));
释放内存,并允许要删除的文件:
var bitmap = new BitmapImage();
var stream = File.OpenRead(imageFilePath);
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
stream.Close();
stream.Dispose();
可选,也冻结的BitmapImage:
bitmap.Freeze();
您可以在窗口的Closed
事件中的图像上调用Dispose()
。我认为也可以使用不同的缓存选项来优化内存占用。
编辑:
你不能调用Dispose(),相反,你可能会考虑BitmapCacheOption.None
。图像将直接从磁盘读取,而不是缓存在内存中。
我试图使用新的BitmapImage(新的Uri(链接),新的RequestCachePolicy(RequestCacheLevel.NoCacheNoStore));'但没有任何区别。内存仍在使用中。 – AgentFire
您可以将对象设置为null
,以便不再引用BitmapImage对象。 在这种情况下,GC应该注意释放资源。 您可以拨打GC.Collect
,但如果使用频率过高,则会影响性能。
在我的情况下,似乎位图缓存是问题。我以前装载位图是这样的:
Bitmap bitmap = new Bitmap();
using(var stream = new FileStream(...))
{
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
}
bitmap.Freeze();
image.Source = bitmap;
不断更换image.Source
以同样的方式刚刚建立起来的内存,手动强制垃圾回收并没有真正帮助。
取而代之的是,禁用缓存并让它使用流(需要将流打开直到图像显示)与手动垃圾收集配对消除了为我建立的内存。
Stream mediaStream;
void DisposeMediaStream()
{
if (mediaStream != null)
{
mediaStream.Close();
mediaStream.Dispose();
mediaStream = null;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
}
}
void Update()
{
DisposeMediaStream();
var bitmap = new BitmapImage();
mediaStream = new FileStream(...);
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.None;
bitmap.StreamSource = mediaStream;
bitmap.EndInit();
bitmap.Freeze();
ControlImage.Source = bitmap;
}
这样我可以通过万吨图像(如Windows照片查看器)和存储周期保持低电平。请注意,图像实际呈现后,流不必保持打开状态。
是的,它在过去的日子里为我工作。 – AgentFire
很好的答案,谢谢。帮了我很多。 – MDDDC