所以我在過去的一週裏一直在處理我的項目中的另一個內存問題。我嘗試了幾個內存分析器,但沒有讓我知道是什麼導致了小內存泄漏。下面的代碼竟然是導致它:列表<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