Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Image control memory leak

My program has a lot of small images (Image controls are small, not the images themselves) and by saying a lot I mean more than 500. These images are generated asynchronously and then assigned to the Image controls, which were initialized before.
Basically my code does the following:

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

There is no memory leak in code that creates the images, I have the following code:

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

Still the problem persists. This happens in the event handler method:

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

With 468 images the program uses about 1Gb of memory and then runs out of it at all. Is my task even possible to achieve using WPF or is the number of images too high? Maybe there is something wrong with my code?
Thanks in advance

like image 255
Cracker Avatar asked Nov 26 '22 19:11

Cracker


1 Answers

You should freeze these images and set their width (or height) to that will be actually used in the application if possible:

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

bitmap.Freeze();
this.images[pageNumber].Source = bitmap;
like image 193
user7116 Avatar answered Dec 06 '22 19:12

user7116