0

I wrote a code to load the image into a <image> control and since i need to edit and save the same image which is used in multiple places, i was in a position to modify the code to avoid Access violation error. Now i'm getting Out of memory exception.

    private BitmapSource LoadImage(string path)
    {
        lock (_syncRoot) //lock the object so it doesn't get executed more than once at a time.
        {
            BitmapDecoder decoder = null;

            try
            {
                //If the image is not found in the folder, then show the image not found.
                if (!File.Exists(path) && (path != null))
                {
                    using (var stream = new System.IO.MemoryStream())
                    {
                        if (!File.Exists(Path.GetTempPath() + "ImageNotFound.jpg"))
                        {
                            System.Drawing.Bitmap ss = Ashley.ProductData.MarketSeries.Presentation.Properties.Resources.ImageNotFound;

                            using (FileStream file = new FileStream(Path.GetTempPath() + "ImageNotFound.jpg", FileMode.Create, FileAccess.Write))
                            {
                                ss.Save(stream, ImageFormat.Jpeg);
                                stream.Position = 0;
                                stream.WriteTo(file);
                            }
                        } 
                    }

                    path = Path.Combine(Path.GetTempPath(), "ImageNotFound.jpg");
                    NoImage = false;
                }
                else
                {
                    if (!EnableForEdit)
                        NoImage = false;
                    else
                        NoImage = true;
                }

                if (!string.IsNullOrEmpty(path) && (!NoImage || File.Exists(path)))
                {
                    using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
                        return decoder.Frames.FirstOrDefault();
                    }

                }
                else
                    return null;
            }
            catch (OutOfMemoryException ex)
            {
                MessageBox.Show("Insufficient memory to handle the process. Please try again later.", "Application alert");                    

                return null;
            }
            catch (Exception ex)
            {
                // Error handling.
                 ShowMessages.AlertBox(ex.Message, MethodInfo.GetCurrentMethod().Name);
                throw ex;
            }
            finally
            {
                decoder = null;
            }
        }
    }

I need to know if there is any memory leak in the above code or is there any better way to load an image which match my requirements.

A Coder
  • 3,039
  • 7
  • 58
  • 129
John
  • 69
  • 1
  • 7

2 Answers2

0

I had something similar to the same issue and solved by loading the image like this,

//Code:

Replace,

 using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
     {
        decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
        return decoder.Frames.FirstOrDefault();
     }

With,

  BitmapImage bi = new BitmapImage();
  bi.BeginInit();
  bi.CacheOption = BitmapCacheOption.OnLoad;
  bi.UriSource = new Uri(path);
  bi.EndInit();
  bi.Freeze();
  return bi;

if needed make the bi object null in your finally block.

A Coder
  • 3,039
  • 7
  • 58
  • 129
0

That code shouldn't cause a leak. But you should consider if you want to freeze the image. x.ImageSource.Freeze();

In what scenarios does freezing wpf objects benefit performace greatly

Also if you think you have a memory leak you should get a profiler. Red Ant's profiler has saved me dozens of times Red Ant's .Net Memory Profiler

Seriously it's worth it, they probably have a free trial or something, but it can find many sources of leaks, like timers, events not being closed properly etc. Very helpful. If you don't like them then go for another solution but if your looking for leaks Visual Studio won't help you, you need a 3rd party solution.

Community
  • 1
  • 1
Kelly
  • 6,992
  • 12
  • 59
  • 76