Использование оператора вокруг диалоговой формы для обеспечения сборки мусора
У нас есть приложение 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();
}
}
В нашем тестировании метод MyForm Dispose() никогда не вызывался для первого примера, но вызывался немедленно для второго примера.
Похоже ли это на разумный подход в качестве краткосрочного обходного пути, пока мы тратим время на отслеживание каждой конкретной проблемы с ресурсами?
Существуют ли другие подходы, которые мы могли бы рассмотреть для краткосрочного обходного пути и / или методологий для выявления и решения этих типов проблем с ресурсами?
3 ответа
Согласно MSDN, вы должны явно вызывать Dispose для форм, показанных с использованием ShowDialog (в отличие от метода Show):
Когда форма отображается в виде модального диалогового окна, нажатие кнопки "Закрыть" (кнопка с буквой X в правом верхнем углу формы) приводит к тому, что форма скрывается, а для свойства DialogResult устанавливается значение DialogResult.Cancel. В отличие от немодальных форм, метод Close не вызывается.NET Framework, когда пользователь нажимает кнопку закрытия формы диалогового окна или задает значение свойства DialogResult. Вместо этого форма скрыта и может быть показана снова без создания нового экземпляра диалогового окна. Поскольку форма, отображаемая в виде диалогового окна, скрыта, а не закрыта, необходимо вызвать метод Dispose формы, когда форма больше не нужна вашему приложению.
Для модальных диалогов вы должны использовать шаблон:
using ( var dlg = new MyDialog() )
{
// other code here to initialize, etc.
dlg.ShowDialog();
}
Поскольку MyDialog является производным от For m, а For m реализует IDisposable, этот шаблон будет правильно очищать ваш диалог.
Это не должно быть "краткосрочным обходным путем", но стандартным способом, которым вы должны вызывать все ваши модальные диалоги.
Немодальные диалоги - другая история. Вам нужно будет отслеживать их самостоятельно и вызывать Dispose в соответствующих точках вашего приложения.
В общем, это хороший способ использовать using
заявление для объектов, которые реализуют IDisposable.
Небольшой пример ситуации:
Допустим, у вас есть сторонний "компонент". Вы не можете знать, что происходит внутри, и, возможно, эти объекты создают временный файл и удаляют файл на Dispose
, Если вы не звоните Dispose()
и не использовать using
файл никогда не будет удален.
В вашем случае вы можете сделать это слишком долго, пока вы открываете форму modal
,