Итак, я боролся с еще одной проблемой памяти в моем проекте на прошлой неделе. Я попробовал несколько профилировщиков памяти, но ничто не дало мне понять, что вызывает небольшую утечку памяти. Вызвал его следующий код:
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 является UserControl, а весь приведенный выше метод просто удаляет ImageControls из FlowLayoutPanel. Метод DisposList () просто вызывает ImageControl.Dispose () для всех переданных ему элементов управления в списке.
Теперь я подумал, что после выхода из этого метода AllList выйдет из области видимости и, следовательно, все его ссылки на ImageControl будут отсутствовать. Таким образом, GC сделает все это. Но это не так. Я нашел это требует
AllList.Clear();
добавлено в конец метода DeleteAll () до того, как AllList вышел из области видимости.
Так что вам всегда нужно явно очищать общий список, чтобы освободить ресурсы? Или я что-то не так делаю выше? Я хотел бы знать, так как я довольно интенсивно использую временные списки в этом проекте.
Хорошо, вот метод 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), где он заставляет ресурсы оставаться, если свойство Visible не установлено в false, прежде чем оно будет уничтожено. Поэтому я переопределил метод Dispose ImageControl, чтобы сделать это.
Да, и DisposeList () также отписывается от обработчика событий:
private void DisposeList( List<ImageControl> IC )
{
for (int i=0;i<IC.Count;i++)
{
IC[i].DoEvent -= ImageButtonClick;
IC[i].Dispose();
}
}