2016-12-26 84 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不會幫你,你需要第三方解決方案。