Утечка памяти в ShowDialog даже после его утилизации
Я создал пример приложения Windows Forms Form, который содержит две формы - form1 и form2.
Form1 содержит кнопку, и при щелчке я показываю form2 в виде диалогового окна, как показано ниже.
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
try
{
form2.ShowDialog();
}
catch (Exception ex)
{
}
finally
{
if (form2 != null)
{
form2.Dispose();
form2 = null;
}
}
}
Затем я проверил приложение, как Нажмите на кнопку, затем оно откроет форму 2, закройте его. и продолжал это в течение примерно 6 раз.
Когда я проверял приложение с DevPartner, оно всегда показывает Form2 form2 = new Form2();
как утечка
Когда я проверял в Интернете, он говорит, что если мы используем ShowDialog, нам нужно избавиться от формы после ее закрытия, то есть, почему я попытался удалить в блоке finally. Но все же он показывает эту линию как протекающую. Может кто-нибудь, пожалуйста, дайте ваши предложения по этой утечке.
3 ответа
Как правило, когда вы используете объект IDisposable, вы должны объявить и создать его экземпляр в операторе using. Оператор using вызывает метод Dispose для объекта правильным образом, а также вынуждает сам объект выходить из области видимости, как только вызывается Dispose. Внутри блока using объект доступен только для чтения и не может быть изменен или переназначен.
Оператор using гарантирует, что Dispose вызывается, даже если возникает исключение, когда вы вызываете методы объекта.
Вы должны исследовать вашу форму Form2, чтобы найти любые подстановки к внешним событиям и корневым ссылкам. Все они должны быть удалены по форме утилизации.
В следующем коде причина утечки - подписка на событие Idle. Подписка удаляется методом Dispose, чтобы избежать утечки.
Form2()
{
Application.Idle += Application_Idle;
}
void Application_Idle(object sender, EventArgs e)
{
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
Application.Idle -= Application_Idle;
}
}
Вероятно, это правила проверки вашего инструмента, поскольку создание экземпляра не входит в try-catch.
Попробуйте это так:
private void button1_Click(object sender, EventArgs e) {
Form2 form2;
try {
form2 = new Form2();
form2.ShowDialog();
} finally {
if (form2 != null) {
form2.Dispose();
form2 = null;
}
}
}
Или даже проще:
private void button1_Click(object sender, EventArgs e) {
using (var form2 = new Form2()) {
form2.ShowDialog();
}
}