Prevent Memory Bloat When Loading Multiple Images In WPF

前端 未结 2 855
甜味超标
甜味超标 2021-01-21 03:35

I have a very simple WPF app which is used to preview images in any given folder one image at a time. You can think of it as a Windows Image Viewer clone. The app has a PreviewK

相关标签:
2条回答
  • 2021-01-21 04:32

    Call .Freeze() on the bitmap object, this sets it in to a read-only state and releases some of the handles on it that prevents it from getting GC'ed.

    Another thing you can do is you can tell the BitmapImage to bypass caching, the memory you see building up could be from the cache.

    CurrentImage.Source = new BitmapImage(new Uri(currentFile), 
                                       new RequestCachePolicy(RequestCacheLevel.BypassCache));
    

    Lastly, if there is not a lot of programs running on the computer putting memory pressure on the system .net is allowed to wait as long as it wants for a GC. Doing a GC is slow and lowers performance during the GC, if a GC is not necessary because no one is requesting the ram then it does not do a GC.

    0 讨论(0)
  • 2021-01-21 04:36

    When you say preview, you probably don't need the full image size. So besides of calling Freeze, you may also set the BitmapImage's DecodePixelWidth or DecodePixelHeight property.

    I would also recommend to load the images directly from a FileStream instead of an Uri. Note that the online doc of the UriCachePolicy says that it is

    ... a value that represents the caching policy for images that come from an HTTP source.

    so it might not work with local file Uris.

    To be on the safe side, you could do this:

    var image = new BitmapImage();
    
    using (var stream = new FileStream(currentFile, FileMode.Open, FileAccess.Read))
    {
        image.BeginInit();
        image.DecodePixelWidth = 100;
        image.CacheOption = BitmapCacheOption.OnLoad;
        image.StreamSource = stream;
        image.EndInit();
    }
    
    image.Freeze();
    CurrentImage.Source = image;
    
    0 讨论(0)
提交回复
热议问题