2016-09-14 3 views
6

Итак, в моих приложениях я стараюсь создавать новые экземпляры форм «на лету», а затем использовать Form.Show() для их отображения (не модально).Каков правильный способ утилизации новой формы без немедленного закрытия?

private void test_click(object sender, EventArgs e) 
{ 
    var form = new myForm(); 
    form.Show(); 
} 

Однако Code Cracker сообщает мне, что эти формы должны быть утилизированы. Итак, я завернул их в инструкцию «using», но затем они закрываются сразу после открытия.

using (var form = new myForm()) 
{ 
    form.Show(); 
} 

Я не хочу использовать Form.ShowDialog(), потому что в некоторых случаях я открываю новые окна, которые только показывают отчеты; Мне не нужно, чтобы они были модными.

+6

Ответ ясен. «Code Cracker» вводит вас в заблуждение. Не используйте 'using' .... Утилизируйте форму, когда это подходит ... –

+0

Я должен согласиться с @ L.B здесь - закрытие окна - это правильная вещь для Dispose(). По определению, правильно реализованный метод Dispose() должен оставить расположенный объект в непригодном для использования состоянии. – EJoshuaS

+1

Чтение этой [темы] (https://social.msdn.microsoft.com/Forums/windows/en-US/cc4acf77-6e7e-46a6-992d-702e314acbdf/howwhen-to-call-dispose-when-using-a -modeless-dialog? forum = winforms), кажется, указывает, что мне не нужно беспокоиться об утилизации. Необязательные формы автоматически GC'd. Я тестировал во время просмотра Task Mananger, и память была исправлена. – javon27

ответ

3

Хм, «код взломщика» представляется очень подходящим термином для этого инструмента, его совет, безусловно, заставил вас написать код, который разбивает вашу программу. Золотое правило: never trust IDisposable advice от инструмента анализа статического кода, ни один из них никогда не имеет достаточного понимания кода исполнение. Они никогда не могут определить, какой вызов Dispose() выполняет задание.

Что он не видит, так это то, что класс Form уже знает, как распоряжаться собой. Это очень легко для этого, объект становится непригодным, когда окно закрывается. Когда окна больше нет, нет причин продолжать использовать объект Form. Роскошь, которая не очень распространена в .NET, но, безусловно, вдохновлена ​​очень умными программистами, которые работали на Xerox 45 лет назад.

Существует только одно специальное правило, которое вы должны иметь в виду: оно не распоряжаться собой, когда вы используете ShowDialog() для отображения окна. Это было преднамеренно, это делает получение результатов диалога слишком рискованным. Использование с использованием оператора для вызова ShowDialog() очень просто сделать, вызов не возвращается, пока окно не будет закрыто.

+0

Вы правы на всех счетах. Я просто ненавижу видеть все squiggly строки из Code Cracker, но в то же время не хочу добавлять правила подавления. Я также не хочу полностью избавляться от него, потому что он дает много идей для этого младшего разработчика. – javon27

+0

Просто отключите специальное правило анализа, это совсем не поможет. Или научитесь слишком не доверять инструментам, делает вас старшим :) –

1

Вы могли бы реализовать somekind менеджера форм, которые будут подписываться на OnFormClosedEvent для каждого вида он показывает, он может распоряжаться им ... что-то вроде:

public class FormManager 
{ 
    public T ShowForm<T>() 
     where T : Form, new() 
    { 
     var t = new T(); 
     t.OnFormClosing += DisposeForm; 
     return t; 
    } 

    void DisposeForm(object sender, FormClosedEventArgs args) 
    { 
     ((Form)sender).Dispose(); 
    } 
} 

Вы могли бы даже пойти так далеко, чтобы реализовать IDisposable и распоряжаться всеми нереализованными формами при размещении менеджера :)

0

Так что согласно ответу на MSDN, модальные формы автоматически удаляются, когда вы их закрываете.

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

+0

Фактически это означает, что GC восстанавливает память, а не вызывает 'Dispose'. В этом случае 'Dispose' не очищает какие-либо собственные ресурсы, поэтому вся память управляется GC, и она освобождается независимо от того, вызывается ли Dispose' или нет. – Cameron

8

Нужно ли мне утилизировать форму после закрытия формы?

Когда вы закроете Form, в окно будет отправлено сообщение WM_CLOSE.Если вы посмотрите на исходный код WmClose метода, который обрабатывает WM_CLOSE сообщение, вы увидите:

  • Для модальных форм (которые вы показали с помощью ShowDialog), метод Dispose не будет называться и форма существует после того, как и вы можете использовать его свойства, чтобы получить некоторые данные, или вы можете показать его снова.

  • Для немодальных форм (которые вы показали с использованием Show), после того, как форма закрыта, вызывается метод Dispose.

Так вот вывод:

  • Когда вы показываете форму с помощью Show метод вам не нужно (и вы не можете) позвонить Dispose. Форма будет удалена после закрытия.

  • Когда вы показываете форму, используя ShowDialog, вам необходимо позвонить по телефону Dispose вручную. Хорошей практикой является использование модальных форм в блоке using.

+1

спасибо, что очень полезно знать, что немодальная форма автоматически получает вызов dispose, а модельная форма - нет. –

Смежные вопросы