2013-04-04 59 views
1

我想用下面的代碼加載圖片:WPF內存問題

 void LoadPictures(int s) 
     { 
      grdScene.Children.Clear(); 
      TabControl tab = new TabControl(); 
      for (int i = s; i <= s+3; i++) 
      { 
       System.Drawing.Bitmap bmp = new System.Drawing.Bitmap("C:\\img\\" + i + ".png"); 
       TabItem tabItem = new TabItem(); 
       tabItem.Header = "Scene " + i; 
       var bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), 
                      IntPtr.Zero, 
                      Int32Rect.Empty, 
                      BitmapSizeOptions.FromEmptyOptions()); 
       Image image = new Image(); 
       image.Source = bitmapSource; 
       tabItem.Content = image; 
       tab.Items.Add(tabItem); 
      } 
      grdScene.Children.Add(tab);//grdScene is Grid 
     } 

它工作正常,但我每次運行這個方法內存正在上升。 然後我嘗試將所有項目設置爲null,但沒有成功。這裏是代碼:

 foreach (var child in grdScene.Children) 
     { 
      TabControl tab1 = (TabControl)child; 
      foreach (TabItem item in tab1.Items) 
      { 
       Image img = (Image)item.Content; 
       img = null; 
      } 
      tab1 = null; 
     } 

我試過GC.Collect()沒有什麼變化。我該怎麼做才能解決這個問題? 任何幫助表示讚賞。

回答

2

你爲什麼要通過代碼隱藏來做到這一點?

從代碼的外觀來看,選項卡項完全由圖像填充。

您可以將tabcontrol綁定到圖像路徑集合,並使用樣式來描述您之後的外觀,它會簡單得多,然後WPF核心將負責圖像加載和內存管理本身。


如果不是可用於您那麼你的​​問題是從你如何加載圖像,你通過不釋放內存給你一個不安全的互操作方法做它的到來,你必須處置youreself .Dispose()

你會更好做位圖:loading the source of a BitmapImage in WPF?

使用BitmapImage很可能是更好的方式去,如果你想留在後臺代碼,而不是互操作的方法做。

SO:

void LoadPictures(int s) 
    { 
     grdScene.Children.Clear(); 
     TabControl tab = new TabControl(); 
     for (int i = s; i <= s + 3; i++) 
     { 
      BitmapImage bmp = new BitmapImage(new Uri("C:\\img\\" + i + ".png")); 
      TabItem tabItem = new TabItem(); 
      tabItem.Header = "Scene " + i; 
      tabItem.Content = new Image(){Source = bmp}; 
      tab.Items.Add(tabItem); 
     } 
     grdScene.Children.Add(tab); 
    } 

應該做的伎倆。

+1

我用位圖的原因是我的實際照片不會在文件系統中。它存儲在數據庫中。在我的例子中,爲了使它更容易,我只是從文件系統中加載它。我正在考慮將二進制圖片轉換爲位圖並將位圖轉換爲BitmapSource。我想我可以直接從字節[]轉換爲Windows.Controls.Image。我以前不知道。這樣可以解決問題。感謝您的幫助! – Dilshod 2013-04-04 21:55:02

+1

@Dilshod @Dilshod沒問題,是的,你可以通過這種方式進行轉換,但是無論何時你使用System.Drawing類或WPF互操作系統,一定要調用'.Dispose',它們是邪惡的類,你會得到內存泄漏到處都是。 – Clint 2013-04-04 21:56:48

2

嘗試調用處置所有IDisposable S,如System.Drawing.Bitmap或更好地利用using ..

using(var bmp = new System.Drawing.Bitmap("C:\\img\\" + i + ".png")) 
{ 
    ..... 
} 
+0

請注意,WPF位圖不能作爲Forms的一次性使用:http://stackoverflow.com/questions/8352787/how-to-free-the-memory-after-the-bitmapimage-is-no-longer-needed – Aybe 2013-04-05 01:04:23