我正在尝试使用以下代码加载图片:
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()
但没有任何变化。我应该怎么做才能解决这个问题?
最佳答案
为什么要通过代码隐藏来执行此操作?
从代码的外观来看,选项卡项完全由图像填充。
您可以将一个选项卡控件绑定(bind)到图像路径集合并使用一种样式来描述您想要的外观,这样会简单得多,然后 WPF 核心将负责图像加载和内存管理本身。
如果这对您不可用,那么您的问题出在您加载图像的方式上,您是通过不安全的互操作方法来加载图像的,该方法不会为您释放内存,您必须处理位图你自己 .Dispose()
你最好这样做:loading the source of a BitmapImage in WPF?
如果您想继续在代码隐藏而不是 Interop 方法中进行操作,使用 BitmapImage
可能是更好的方法。
所以:
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);
}
应该可以解决问题。
关于c# - WPF内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15821983/