В чем разница между этими методами для закрытия моего приложения?

В основном у меня есть основная форма, которая при загрузке открывает дочернюю форму для входа в систему пользователя. Когда они отменяют или закрывают эту форму для входа, мне нужно закрыть все приложение.

Но, похоже, существует несколько способов закрыть программу С#:

  • Application.Exit();

  • Application.ExitThread();

  • Environment.Exit(1);

  • Process.GetCurrentProcess().Kill();

  • SFTPClient.LDAPLoggedIn = false; Close();

EDIT: Извините, если это не ясно: оно устанавливает свойство в объекте контроллера, чтобы указать, что сбой входа. После открытия дочерней формы я бы проверил это свойство в родительской форме, чтобы узнать, должна ли программа продолжать или нет. Это в основном переносит ответственность за выход из программы родителям без исключения.

6: throw new Exception("User closed the form");

Я вижу, что есть два способа его обработки:

  • Информирование родителя о том, что что-то пошло не так (как в 5 и 6.)
  • Закрытие программы из дочерней формы.

Является ли одна из этих двух рассмотренных лучше?

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

UPDATE: Спасибо за ответы. Для тех, кто ищет этот вопрос в будущем и любопытных людей, это было моим решением в конце:

private void FormMain_Load(object sender, EventArgs e)
{
    if (new FormLogin().ShowDialog(this) == DialogResult.Cancel) Close();
}

и

private void buttonCancel_Click(object sender, EventArgs e)
{
    Close();
}

Я обнаружил, что когда форма закрывается нажатием кнопки "X", DialogResult устанавливается на "Отмена автоматически", поэтому все, что мне нужно сделать, это Close()

Ответы

Ответ 1

Если вы хотите изящно обрабатывать исключение в последнем случае, это нормально (не очень хорошо) - пока это необычная ситуация для вашего приложения. В противном случае я бы создал новый метод, который показывает форму как диалог с логическим. Если логическое значение возвращается false (иначе пользователь закрыл форму), я тогда обработал бы приложение, закрытое оттуда (используя Application.Exit()).

По моему скромному мнению, очень плохая практика заключается в том, чтобы закрыть приложение от ребенка, а не сообщать родителям. Единственный раз, когда я согласен с этим, в ситуации FailFast, которые очень редки.


Этот метод останавливает все запущенные петли сообщений во всех потоках и закрывает все окна приложения. Этот метод не заставит приложение выйти. Метод Exit обычно вызывается из цикла сообщений и принудительно запускает Run. Чтобы выйти из цикла сообщений только для текущего потока, вызовите ExitThread.

См. выше.


Завершает этот процесс и предоставляет базовой операционной системе указанный код выхода.


Убивает принудительное завершение процесса, а CloseMainWindow запрашивает только завершение. Когда выполняется процесс с графическим интерфейсом, его цикл сообщения находится в состоянии ожидания. Цикл сообщений выполняется каждый раз, когда Windows-сообщение отправляется процессу операционной системой.


  • SFTPClient.LDAPLoggedIn = false; Close();

После пояснения в комментарии (передает поток обратно родительскому и ручками оттуда), это, безусловно, лучший способ сделать это.


  • throw new Exception("User closed the form");

Выдает исключение из вызывающего процесса. Если это основной поток, он будет генерировать исключение очень уродливым способом.

Ответ 2

Все эти способы для завершения приложения слишком сложны и полезны в разных сценариях, но не в вашем.

Вы можете слегка перепроектировать ваше приложение, чтобы решить вашу проблему более элегантным способом. В основном методе вы можете отображать форму входа, и если пользователи нажимают кнопку "отменить", вы просто выходите из основного метода. В противном случае вы увидите основную форму:

class Program {
  static void Main(String[] args) {
     if ( Login.Show() ) {
        //Show main form for your application
     }
     //otherwise you simply return from Main method
  }
}

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

Ответ 3

Вы должны использовать Form.Close(), а не Application.Exit. Как отмечается в документации к MSDN, события, такие как Form.Close и Form.Closing, не срабатывают при использовании Application.Exit.

Ответ 4

Спасибо OP за ваше решение, просто хотел добавить к нему.

Чтобы закрыть свою дочернюю форму и вернуть что-то другое, кроме Отмена, к родительскому:

this.DialogResult = DialogResult.OK;
this.Close();