gpt4 book ai didi

wpf - 您如何确保 WPF 从内存中释放大型 BitmapSource?

转载 作者:行者123 更新时间:2023-12-03 21:23:18 26 4
gpt4 key购买 nike

系统:Windows XP SP3,.NET 3.5,4GB 内存,双 1.6GHz

我有一个 WPF 应用程序,可以加载和转换(使用 Storyboard动画)非常大的 PNG。这些 PNG 的分辨率为 8190x1080。当应用程序运行时,它似乎会缓存图像,系统内存会慢慢增加。最终它会阻塞系统并抛出 OutOfMemoryException。

以下是我目前正在尝试解决此问题的步骤:

1)我正在从应用程序中删除 BitmapSource 对象

2)当我加载 BitmapSource 时,我将 BitmapSource BitmapCacheOption 设置为 None

3) 加载后,我将卡住 BitmapSource。

4)我将删除对使用源的图像的所有引用以及对源本身的任何引用。

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

希望弄清楚为什么 WPF 会卡在这些图像的内存上,以及确保用于加载它们的内存被正确恢复的可能解决方案。

最佳答案

你当然在这方面做了很多工作。我认为主要问题是 BitmapCacheOption.None 不会阻止底层 BitmapDecoder(s) 被缓存。

有几个棘手的解决方案,例如执行 GC.Collect(),从 300 个不同的 Uris 加载 300 个小图像,然后再次调用 GC.Collect(),但简单的方法很简单:

无需从 Uri 加载,只需构造一个 Stream 并将其传递给 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,加载的图片仍然会被插入到缓存中。不同之处在于缓存中的现有图像被忽略。

关于wpf - 您如何确保 WPF 从内存中释放大型 BitmapSource?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1684489/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com