WPF 图像控件内存泄漏问题

5

我的程序有很多小图像(图像控件很小,而不是图像本身),具体来说,超过了500张。这些图像是异步生成的,并分配给事先初始化的Image控件。

基本上,我的代码执行以下操作:

            filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}.JPG", Guid.NewGuid().GetHashCode().ToString("x2")));
            converter.ConvertPdfPageToImage(filename, i);
            //Fire the ThumbnailCreated event
            onThumbnailCreated(filename, (i - 1));  

代码中创建图像的部分没有内存泄漏,以下是代码:

            string[] files = Directory.GetFiles("C:\\Users\\Daniel\\Pictures", "*.jpg");
            for(int i=0; i<files.Length; i++){
                onThumbnailCreated(files[i], i);
            } 

问题仍然存在。 这发生在事件处理程序方法中:

    void Thumbnails_ThumbnailCreated(ThumbnailCreatedEventArgs e, object sender)
    {
        //Since we generate the images async, we need to use Invoke
        this.parent.Dispatcher.Invoke(new SetImageDelegate(SetImage), e.Filename, e.PageNumber);
    }

    private void SetImage(string filename, int pageNumber)
    {
        BitmapImage bitmap = new BitmapImage();
        bitmap.BeginInit();
        //I am trying to make the Image control use as less memory as possible
        //so I prevent caching
        bitmap.CacheOption = BitmapCacheOption.None;
        bitmap.UriSource = new Uri(filename);
        bitmap.EndInit();
        //We set the bitmap as the source for the Image control
        //and show it to the user
        this.images[pageNumber].Source = bitmap;
    }

使用了468个图像,程序占用了约1GB的内存,然后完全耗尽了。 使用WPF是否可以实现我的任务?还是图像数量太多了?也许我的代码有问题吗?
提前感谢。


你是否在使用未安装SP1的3.5框架上的WPF? - Rafal
@Rafal .NET Framework 4.0。不确定SP。 - Cracker
@Rafal,所谓的小图像是指“Image”控件的大小。这些图像本身相当大,大约为700x1000。 - Cracker
2
为什么你不想使用BitmapCacheOption.OnLoad呢? - Lonli-Lokli
我遇到了这个问题。加载18个BitmapImages会占用1GB的内存。有没有一种方法只在显示图像时将其加载到内存中? - AndrewRalon
显示剩余3条评论
3个回答

4

如果可能的话,您应该冻结这些图像并设置它们的宽度(或高度)为实际在应用程序中使用的尺寸:

// ...
bitmap.DecodePixelWidth = 64; // "displayed" width, this improves memory usage
bitmap.EndInit();

bitmap.Freeze();
this.images[pageNumber].Source = bitmap;

你知道这些图像在应用程序中实际使用的尺寸吗?也就是说,这些图像是否比缩略图要大? - user7116
这些图片比显示的缩略图要大。 - Cracker
啊,WPF会在内存中保留整个图像数据(加上开销),除非您在创建时使用DecodePixelWidth(或DecodePixelHeight,但不是两者都)告诉它丢弃该信息。 - user7116
现在好多了。非常感谢!不过,仍然需要254 MiB来存储400张图片。这是最好的结果吗? - Cracker
可能,这些400个元素同时显示吗?如果这些元素在“ItemsControl”中,您应该考虑其他缓存选项或虚拟化。 - user7116

-4

试试这个:

private void SetImage(string filename, int pageNumber)
{
    using (BitmapImage bitmap = new BitmapImage())
    {
        bitmap.BeginInit();
        //I am trying to make the Image control use as less memory as possible
        //so I prevent caching
        bitmap.CacheOption = BitmapCacheOption.None;
        bitmap.UriSource = new Uri(filename);
        bitmap.EndInit();
        this.images[pageNumber].Source = bitmap;
    }
}

当你完成位图操作后,这将处理掉它们。


3
很明显他在使用位图,因为他将其分配给images。调用Dispose可能确实有帮助,但肯定不是你放置它的地方。 - Cory Nelson
@CoryNelson,你说得完全正确,我需要在整个程序运行期间显示这些图像。 - Cracker

-4

@sixlettervariables:为什么很不可能?除非答案是错误的,否则为什么要点踩?如果 OP 正在连接事件处理程序并且没有正确地处理它们,那么很有可能会导致内存泄漏。我的回答是一个有效的建议。 - Shai Cohen
我没有看到任何关于事件处理程序的错误代码。这也不是OP手头问题的原因。 - user7116
@sixlettervariables:事实上,这不是OP所遇到的问题并不重要。我的建议仍然是有效和可行的。如果您能撤销负评,我将不胜感激。谢谢。 - Shai Cohen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接