У меня есть приложение, которое я создаю, которое создает большое количество элементов управления Windows (кнопок и меток и т. Д.). Все они создаются динамически с помощью функций. У меня проблема в том, что когда я удаляю элементы управления и удаляю их, они не удаляются из памяти.
void loadALoadOfStuff()
{
while(tabControlToClear.Controls.Count > 0)
tabControlToClear.Controls[0].Dispose();
//I even put in:
GC.Collect();
GC.WaitForPendingFinalizers();
foreach(String pagename in globalList)
tabControlToClear.Controls.Add(MakeATab(pagename));
}
TabPage MakeATab(string tabText)
{
TabPage newT = new MakeATab();
newT.Text = tabText;
//Fill page with controls with methods like this
return newT;
}
Теперь по какой-то причине, это просто не возвращает мне память, поэтому, когда процесс запускается 5 раз, у меня заканчивается нехватка памяти. Я новичок в объектах и контролирую утилизацию, но просмотр огромной сети все еще не дал мне никаких указаний, поэтому, если у кого-то из вас есть идея, я был бы рад ее услышать.
ОБНОВЛЕНИЕ: Я наблюдал за созданием и уничтожением пользовательских объектов (TaskManager) и заметил, что я создаю вкладку, добавляю обработчик кликов, добавляю панель, добавляю 2 кнопки с обработчиками кликов, всплывающими подсказками и фоновыми изображениями (я думаю, вот где проблема). Приложение говорит, что оно создает 8 новых элементов, но когда я запускаю утилизацию, я удаляю только 4 из памяти. Я пытался удалить обработчики событий, но, похоже, это не имеет значения.
РЕШЕНО !!! Когда я добавлял новые элементы на панель, я передавал им всплывающую подсказку (глупо, но я учусь). Для тех, у кого такая же проблема, (благодаря комментариям и указаниям нижеприведенных людей. Я обнаружил, что для того, чтобы сделать элемент управления действительно доступным (как я понимаю, я так неправильно его назвал):
1: ЕСЛИ У ВАС ЕСТЬ ИНСТРУМЕНТАЛЬНЫЙ СОВЕТ, УБЕДИТЕСЬ, ЧТО ЭТО ДОСТУПНО! НЕ ДЕЛАЙТЕ ТО, ЧТО Я СДЕЛАЛ! Например:
Это НЕПРАВИЛЬНО!
TabPage MakeATab(string tabText)
{
TabPage newT = new MakeATab();
ToolTip myTip = new ToolTip();
newT.Text = tabText;
//Fill page with controls with methods like this
myTip.SetToolTip(newT, "Something to say");
return newT;
}
Если вы сделаете это, вы потеряете указатель на всплывающую подсказку, и поскольку всплывающая подсказка не является дочерней по отношению к объекту, к которому она подключена (скорее, всплывающая подсказка делает сильную ссылку на элемент управления), то даже если вы уничтожите элемент управления, всплывающая подсказка, к которой вы не можете получить доступ, сохраняет объект живым.
2: Прежде всего, вызовите toolTip.RemoveAll (). Это удаляет все его связи с элементами управления. Обратите внимание, что если вы использовали этот совет для других элементов управления, они просто потеряли свою подсказку.
3: Удалить все внутренние элементы управления из базового элемента управления. ControlCollection (если они используют неуправляемую память, я думаю. Я делаю это, потому что это заставляет мое приложение работать так ...)
4: удалить любые пользовательские обработчики событий.
5: наконец, избавьтесь от объекта. Я сделал функцию быстрого повторения, которая делает это довольно хорошо.
private void RecursiveDispose(Control toDispose)
{
while (toDispose.Controls.Count > 0)
RecursiveDispose(toDispose.Controls[0]);
if (toDispose.BackgroundImage != null)
BackgroundImage = null;
if (toDispose.GetType() == typeof(Button))
toDispose.Click -= [Your Event];
else if (toDispose.GetType() == typeof(TabPage))
toDispose.DoubleClick -= [Your Event];
else if (toDispose.GetType() == typeof(Label))
toDispose.MouseMove -= [Your Event];
toDispose.Dispose();
}
Это очень грубо, и, вероятно, есть гораздо лучший способ сделать это, но если кто-то не может придумать это, это придется делать. Спасибо за вашу помощь всем. Возможно, вы просто сохранили весь мой проект.