C# WPF,在循环中加载图像(BitmapImage)
我对BitmapImage类有问题。我知道有几个类似的问题,但我找不到这个问题的答案 基本上,当我加载几次大图片时,它会抛出无声异常。我试图创建一个简单的应用程序来解决这个问题 实际情况当然不同,这只是为了重现。比如说,在按钮点击事件中,我们有:C# WPF,在循环中加载图像(BitmapImage),c#,wpf,memory,memory-leaks,bitmapimage,C#,Wpf,Memory,Memory Leaks,Bitmapimage,我对BitmapImage类有问题。我知道有几个类似的问题,但我找不到这个问题的答案 基本上,当我加载几次大图片时,它会抛出无声异常。我试图创建一个简单的应用程序来解决这个问题 实际情况当然不同,这只是为了重现。比如说,在按钮点击事件中,我们有: var openFileDialog=new OpenFileDialog(); if (openFileDialog.ShowDialog()==true) { BitmapI
var openFileDialog=new OpenFileDialog();
if (openFileDialog.ShowDialog()==true)
{
BitmapImage bitmapImage = null;
for (int i = 0; i < 50; i++)
{
if (bitmapImage != null)
{
bitmapImage.StreamSource.Dispose();
bitmapImage.DecodeFailed -= bitmap_DecodeFailed;
canvas.Bitmap = null;
}
bitmapImage = Load(openFileDialog.FileName);
Thread.Sleep(100);
Debug.WriteLine(GC.GetTotalMemory(false));
}
canvas.Bitmap = bitmapImage;
canvas.InvalidateVisual();
}
它在几次迭代后失败(DecodedFailed)(它没有崩溃,只是引发了事件)。例外情况是:
System.OutOfMemoryException:内存不足,无法继续执行程序。
位于System.Windows.Media.Imaging.BitmapSource.CreateCachedBitmap(BitmapFrame框架、BitmapSourceSafeMILHandle wicSource、BitmapCreateOptions createOptions、BitmapCacheOption缓存选项、BitmapPalette调色板)
在System.Windows.Media.Imaging.CachedBitmap.FinalizeCreation()中
在System.Windows.Media.Imaging.CachedBitmap.EndInit()中
位于System.Windows.Media.Imaging.CachedBitmap..ctor(BitmapSource源、BitmapCreateOptions createOptions、BitmapCacheOption缓存选项)
位于System.Windows.Media.Imaging.BitmapImage.FinalizeRecreation()处
我尝试了不同的方法:
-更改缓存模式
-处理流。
-冻结
-如果我没有附加任何事件,也会发生这种情况(我知道BitmapImage的事件存在众所周知的内存泄漏)
请注意,没有任何绑定。我在画布上画了一幅画,就这样。我使用测试工具测试了代码
并不总是在4次迭代之后。这一切都取决于可用内存和图片大小。如果在调用
Load
之前通过调用GC.Collect()
在每个循环周期中强制垃圾收集,它将如何工作?在许多情况下(并非总是),强制收集工作-可用内存是恒定的。然而,我不想强制GC,当内存不足时,收集应该自动启动。
public BitmapImage Load(string path)
{
var memoryStream = new MemoryStream();
using (var reader = new BinaryReader(File.Open(path, FileMode.Open)))
{
byte[] allData = reader.ReadBytes((int) reader.BaseStream.Length);
memoryStream.Write(allData, 0, allData.Length);
}
memoryStream.Position = 0;
var bitmap = new BitmapImage();
bitmap.DecodeFailed += bitmap_DecodeFailed;
bitmap.BeginInit();
bitmap.StreamSource = memoryStream;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
return bitmap;
}
void bitmap_DecodeFailed(object sender, ExceptionEventArgs e)
{
MessageBox.Show(e.ErrorException.ToString());
Environment.FailFast(e.ErrorException.ToString());
}