2013-04-04 83 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