2016-12-26 44 views
0

我编写了一个代码来将图像加载到<image>控件中,并且由于我需要编辑和保存在多个位置使用的相同图像,我的位置是修改代码避免Access violation error。现在我得到Out of memory exception加载图像时发生内存泄漏C#

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

我需要知道,如果在上面的代码中的任何内存泄漏或有没有更好的方式来加载符合我的要求,这图像。

回答

0

我有类似的同样的问题,并通过加载这样的图像解决了一些东西,

//代码:

更换,

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

有了,

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

如果需要在您的01中使bi对象区块。

+0

需要一些时间来检查这是否工作。谢谢 – John

0

该代码不应该导致泄漏。但是你应该考虑是否要冻结图像。 x.ImageSource.Freeze();

In what scenarios does freezing wpf objects benefit performace greatly

此外,如果你认为你有内存泄漏你应该得到一个分析器。 红蚂蚁的探查已经救了我几十次Red Ant's .Net Memory Profiler

认真它是值得的,他们可能是在免费试用或东西,但它可以找到泄漏的来源很多,如计时器,事件没有被正常关闭等非常有用。如果你不喜欢它们,那么去找另一个解决方案,但是如果你正在寻找漏洞,Visual Studio不会帮你,你需要第三方解决方案。