Использование оператора вокруг диалоговой формы для обеспечения сборки мусора - PullRequest
8 голосов
/ 29 ноября 2011

У нас есть приложение Windows Forms, которое содержит тысячи форм.

Многие из них временно отображаются в виде диалогов с помощью метода ShowDialog ().

Это приложение существует уже много лет, и мы обнаружили, что многие формы не получают своевременный сбор мусора из-за различных утечек ресурсов в форме или используемых элементов управления.

В частности, мы нашли примеры ресурсов GDI +, которые не утилизируются должным образом, хотя могут быть и другие типы утечек ресурсов, которые еще не были охарактеризованы.

Хотя правильный путь решения этой проблемы, очевидно, состоит в том, чтобы пройти через каждую форму и каждый элемент управления и устранить все проблемы с ресурсами. Это займет некоторое время.

В качестве краткосрочной альтернативы мы обнаружили, что явный вызов Dispose () в форме, по-видимому, инициирует процесс сборки мусора, и форма и ее ресурсы немедленно освобождаются.

Мой вопрос заключается в том, будет ли разумным обходным решением обернуть каждый блок ShowDialog () формы в операторе using, чтобы Dispose () вызывался после отображения формы, а также это было бы хорошей практикой для введения в вообще?

Например, измените существующий код из этого:

public void ShowMyForm()
{
    MyForm myForm = new MyForm();
    myForm.ShowDialog();
}

К этому:

public void ShowMyForm()
{
    using (MyForm myForm = new MyForm())
    {
        myForm.ShowDialog();
    }
}

В нашем тестировании метод Dispose () MyForm никогда не вызывается для первого примера, но вызывается немедленно для второго примера.

Кажется ли это разумным подходом в качестве краткосрочного обходного пути, пока мы тратим время на отслеживание каждой конкретной проблемы с ресурсами?

Существуют ли другие подходы, которые мы могли бы рассмотреть для краткосрочного обходного пути и / или методологий для выявления и решения этих типов проблем с ресурсами?

Ответы [ 3 ]

12 голосов
/ 29 ноября 2011

Согласно MSDN , вы должны явно вызывать Dispose для форм, показанных с использованием ShowDialog (в отличие от метода Show):

Когда форма отображается как модальное диалоговое окно, нажмите Закрыть кнопка (кнопка с крестиком в правом верхнем углу формы) вызывает скрытие формы и установку свойства DialogResult в DialogResult.Cancel. В отличие от немодальных форм, метод Close не вызывается .NET Framework, когда пользователь щелкает форму закрытия кнопка диалогового окна или задает значение свойства DialogResult. Вместо этого форма скрыта и может быть показана снова без создания новый экземпляр диалогового окна. Потому что форма отображается в виде диалога поле скрыто, а не закрыто, необходимо вызвать метод Dispose форма, когда форма больше не нужна вашему приложению.

2 голосов
/ 29 ноября 2011

Для модальных диалогов вы должны использовать шаблон:

using ( var dlg = new MyDialog() )
{
    // other code here to initialize, etc.
    dlg.ShowDialog();
}

Поскольку MyDialog является производным от Форма , а Форма реализует IDisposable , этот шаблон будет правильно очищать ваш диалог.

Это не должен быть «краткосрочный обходной путь», а стандартный способ вызова всех ваших модальных диалогов.

Немодальные диалоги - другая история. Вам нужно будет отследить их самостоятельно и позвонить Утилизируйте в соответствующих точках вашего заявления.

1 голос
/ 29 ноября 2011

В общем, это хороший способ использовать оператор using для объектов, которые реализуют IDisposable.

Небольшой пример ситуации:

Допустим, у вас есть сторонний "компонент",Вы не можете знать, что происходит внутри, и, возможно, эти объекты создают временный файл и удаляют файл на Dispose.Если вы не звоните Dispose() и не используете using, файл никогда не будет удален.

В вашем случае вы можете делать это слишком долго, пока открываете форму modal.

...