系统:Windows XP SP3,.NET 3.5,4GB RAM,双1.6GHz的

我有负载和转变(使用故事板动画)非常大的PNG WPF应用程序。这些PNG图像的分辨率8190x1080。在应用程序运行它似乎缓存图像和系统内存慢慢向上蔓延。最终,它扼流圈系统并抛出OutOfMemoryException异常。

下面是我目前正在设法解决这个问题的步骤:

1),我从应用程序移除的BitmapSource对象

2)我设定的BitmapSource BitmapCacheOption为无时我加载的BitmapSource

3)我冻结的BitmapSource一旦它的加载。

4)我正在删除该使用源以及到源本身。

的任何引用的图像的所有参考文献

5)手动调用GC.Collect的()上述步骤已经完成之后。

希望能找出为什么WPF是挂到存储器上的这些图像和一个可能的解决方案,以确保存储器用来加载它们被适当地恢复。

有帮助吗?

解决方案

您肯定已经把这个大量的工作。我认为主要问题是,BitmapCacheOption.None并不妨碍底层BitmapDecoder(多个)被缓存。

有作为再次做GC.Collect的(),装载从300个不同的URI 300个小的图像,并调用GC.Collect的()到这个这样几个棘手的解决方案,但简单的一个是直接的:

代替从URI加载的,只是构造一个流,并将其传递给BitmapFrame的构造:

var source = new BitmapImage();
using(Stream stream = ...)
{
  source.BeginInit();
  source.StreamSource = stream;
  source.CacheOption = BitmapCacheOption.OnLoad;    // not a mistake - see below
  source.EndInit();
}

这应该工作的原因是由流,其装载完全禁用缓存。不仅是顶层源没有被高速缓存,但是,没有内部解码器要么缓存。

为什么BitmapCacheOption.OnLoad?这似乎违反直觉,但这个标志有两个作用:它能够缓存如果缓存是可能的,它会导致负荷EndInit发生()。在我们的情况下的高速缓存是不可能的,因此,所有它不会造成的负荷立即发生。

显然,你会想要把你的UI线程运行此代码,然后冻结的BitmapSource以便您可以通过移动它。

您也可能想知道为什么我没有用BitmapCreateOptions.IgnoreImageCache。除了一个事实,即缓存是不可能任何没有给定URI的IgnoreImageCache不能完全忽略图像缓存:它仅会忽略它的阅读。因此,即使IgnoreImageCache设定,加载的图像仍然插入到缓存中。不同的是,在高速缓存中已有的图像将被忽略。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top