所以我在过去的一周里一直在处理我的项目中的另一个内存问题。我尝试了几个内存分析器,但没有让我知道是什么导致了小内存泄漏。下面的代码竟然是导致它:列表<T>。清除 - 是否需要调用?
private void DeleteAll(FlowLayoutPanel flp)
{
List<ImageControl> AllList = GetAllList(flp);
List<ImageControl> LockedList = GetLockedList(flp);
for (int i = 0; i < LockedList.Count; i++)
{
AllList.Remove(LockedList[i]);
}
flp.SuspendLayout();
for (int i = 0; i < AllList.Count; i++)
{
flp.Controls.Remove(AllList[i]);
}
DisposeList(AllList);
flp.ResumeLayout();
}
在代码中,ImageControl是一个用户控件,和上方的整个方法刚从FlowLayoutPanel的去除ImageControls的。 DisposList()方法为传递给它的列表中的所有控件调用ImageControl.Dispose()。现在
,我认为,一旦这种方法已经退出,AllList会超出范围,因此其所有的ImageControl的引用将是不存在的。所以GC会做这件事。但事实并非如此。我发现它需要
AllList.Clear();
在AllList超出范围之前,将其添加到DeleteAll()方法的末尾。
所以你必须始终明确地清除泛型列表,以腾出资源?或者是我在上面做错了什么?我想知道,因为我在这个项目中大量使用临时列表。
好吧,这里的GetAllList方法。看起来并不像一个问题,我说:
private List<ImageControl> GetAllList(FlowLayoutPanel flp)
{
List<ImageControl> List = new List<ImageControl>();
for (int i = 0; i < flp.Controls.Count; i++)
{
List.Add((ImageControl)flp.Controls[i]);
}
return List;
}
顺便说一句,如果你看到我过去的几个主题在这里,我一直在争取的内存泄漏我的追求,成为一个精通C#程序员:)我增加了DisposeList ()方法,因为我已经阅读Dispose()应该在实现IDisposable的任何对象上调用,而UserControl会这样做。我还需要一种方法来修复ToolStrip类(ImageControl包含的)的“bug”,它会导致资源保留,除非Visible属性在其销毁之前设置为false。所以我重写了ImageControl的Dispose方法来做到这一点。
private void DisposeList(List<ImageControl> IC)
{
for (int i=0;i<IC.Count;i++)
{
IC[i].DoEvent -= ImageButtonClick;
IC[i].Dispose();
}
}
注意这里是“减名单”一个更加简洁和更清晰的方式:'VAR减去= listA.Except(数组listB);' (这需要'使用System.Linq') – 2010-06-19 22:25:19