Утечка памяти в 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();
    }
}
Другие вопросы по тегам