WPF,循环加载图像(BitmapImage)

时间:2014-06-12 09:25:00

标签: c# wpf memory memory-leaks bitmapimage

我的BitmapImage类有问题。我知道有一些类似的问题,但我找不到该特定问题的答案。

基本上当我加载几张大图片时,它会抛出无声的异常。我试图创建一个简单的应用程序来解决这个问题。

真实场景当然是不同的,这只是为了重现它。让我们说按钮点击事件中的某个地方:

        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();
        }

在循环中,我们加载50次相同的图片(逐个)。它模拟用户可以更改图片的场景。它应该替换前一个,然后重新加载下一个。我不明白为什么它在4次迭代后失败了。如果第一次和第二次有足够的内存加载它,为什么以后没有足够的重新加载它?

这是我加载图片的方式:

    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());
    }

经过几次迭代后失败(DecodedFailed)(它会崩溃,只会引发事件)。例外是:

System.OutOfMemoryException:内存不足,无法继续执行程序。    在System.Windows.Media.Imaging.BitmapSource.CreateCachedBitmap(BitmapFrame框架,BitmapSourceSafeMILHandle wicSource,BitmapCreateOptions createOptions,BitmapCacheOption cacheOption,BitmapPalette调色板)    在System.Windows.Media.Imaging.CachedBitmap.FinalizeCreation()    在System.Windows.Media.Imaging.CachedBitmap.EndInit()    在System.Windows.Media.Imaging.CachedBitmap..ctor(BitmapSource源,BitmapCreateOptions createOptions,BitmapCacheOption cacheOption)    在System.Windows.Media.Imaging.BitmapImage.FinalizeCreation()

我尝试了不同的东西: - 改变缓存模式 - 处理流。 - 冻结 - 如果我没有附加任何事件也会发生(我知道BitmapImage的事件有众所周知的内存泄漏)

请注意,没有任何约束。我在画布上画了一张照片就是这样。我使用http://followhislight.files.wordpress.com/2013/08/map_of_the_world_1998.jpg测试了代码。

经过4次迭代后并不总是如此。这一切都取决于可用的内存和图片大小。

0 个答案:

没有答案