Удалить форму после закрытия

у меня появилась новая проблема с открытием и закрытием формы в C#.

моя проблема заключается в том, как избавиться от формы после закрытия .

вот мой код :

.cs:
static class Program
{
    public static Timer timer;

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        timer = new Timer { Interval = 1000};
        timer.Start();

        Application.Run(new Form1());
    }
}

форма form1.cs:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 form = new Form2();
        form.ShowDialog();
       /// I've tried Dispose() method . but didn't work
    }
}

формы Form2.cs:

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {
        Program.timer.Tick += timer_Tick;    
        Close();
        // I've tried Dispose() method instead of Close() but didn't work
    }

    private int count = 0; 
    void timer_Tick(object sender, EventArgs e)
    {
        count++;
        if (count == 5) MessageBox.Show("");
    }
}

редактировать : Мой вопрос: почему окно сообщения отображается через 5 секунд, когда form2 закрылся!

5 ответов


Edit: этот вопрос оказывается о Dispose.

во-первых, Dispose имеет отношение к сбору мусора. Происходит следующее:

  1. у вас есть глобальный экземпляр таймера
  2. вы создаете form2
  3. Form2 подписывается на таймер
  4. Form2 закрыт и / или удален
  5. событие таймера срабатывает, увеличивает счетчик и показывает MessageBox
  6. событие таймера продолжает стрелять, пока приложение закрывается.

главное, чтобы понять, что Close / Dispose только изменить статус формы, они не (не могут) "удалить" экземпляр. Таким образом, (закрытая) форма существует, поле счетчика все еще существует, и событие срабатывает.


OK, часть 1:

A using () {} блок был бы лучше, но это должно работать:

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 form = new Form2();
        form.ShowDialog();
       /// I've tried Dispose() method . but didn't work
        form.Dispose(); // should work
    }

если нет, пожалуйста, опишите "не работает".


    private void Form2_Load(object sender, EventArgs e)
    {
        Program.timer.Tick += timer_Tick;    
        Close();
       /// I've tried Dispose() method instead of Close() . but didn't work
    }

Это странно, но я предполагаю, что что это искусственный код вопроса.

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

  1. не делайте этого (дайте Form2 это собственный таймер)
  2. используйте событие FormClosed для отмены подписки:Program.timer.Tick -= timer_Tick;

самый простой и надежный способ избавиться от Form после использования-поместить использование внутри блока using

using (Form2 form = new Form2()) {
  form.ShowDialog();
}

блок using в C# - это конструкция, которая существенно расширяет вышеуказанное в следующий код.

Form2 form;
try {
  form = new Form2(); 
  ...
} finally {
  if ( form != null ) {
    form.Dispose();
  }
}

Это старый вопрос, но он затрагивает некоторые интересные моменты о том, как объекты работы. Форма-это, по существу, объект. Все объекты одного класса используют одни и те же методы, но каждый из них имеет свои собственные данные. Что это значит? Это означает, что закрытие или удаление объекта не освобождает/удаляет / удаляет любой код из памяти. Только данные. Все это касалось объектов вообще, независимо от языка.

теперь, конкретно о вашем коде. Разберем какая черта!--0--> делает. Это дает указатель на вашу функцию в форма объекта до таймер объект. Итак, теперь, независимо от того, что вы делаете с форма объекта на таймер объект будет продолжать вызывать эту функцию. Объект timer не заботится о вашей форме и даже не знает о существовании объекта формы. Он заботится только о функция, которой вы передали указатель на. Насколько объект таймер обеспокоена, эта функция является автономной функцией.

что формирует.Закрыть() сделать? Форма.Close () удаляет ресурсы, используемые формой, он же отмечает элементы управления формы для сбора мусора Если форма отображается с помощью ShowDialog. В этом случае Dispose() необходимо вызвать вручную. MSDN

Излишне говорить(или, может быть, не так излишне) , что если закрытие / удаление формы очистит функцию от памяти, объект timer будет имеют недопустимый указатель и ваша программа будет авария через 5 секунд.


возможно, я неправильно понял вопрос, но я думаю, что джентльмены должны знать это, чтобы закрыть форму (скажем, form2), открытую как Form2.ShowDialog (), вам нужно установить Form2.Свойство dialogresult в форме Form2. Просто установите этот элемент, чтобы закрыть форму и вернуть результат.


форма.ShowDialog () показывает форму в виде модального диалога. Это означает, что вызов не возвращается, пока форма не будет закрыта.
Обратите внимание, что нажатие кнопки Закрыть X в модальном диалоговом окне не закрывает форму, а просто скрывает ее. Полагаю, именно это вас и смущает. Если вы хотите, чтобы код в form1 продолжал выполняться, а не блокировать, вы должны вызвать Show() вместо ShowDialog(). Немодальное будет закрыть, когда X щелкают.

Если вы хотите блокировать модальный диалог, вы должны окружить форму блоком using, как описано в других ответах.
При построении модального диалога вы обычно добавляете кнопку" ОК " или аналогичную и устанавливаете свойство AcceptButton формы на эту кнопку, чтобы позволить пользователю закрыть форму, нажав enter. Аналогично, вы можете добавить кнопку "Отмена" и установить свойство CancelButton для захвата ключа Esc.
Добавьте обработчик щелчка к двум кнопкам, установите свойство DialogResult формы соответствующим образом и вызовите Закрывать.)(