В чем разница между этими методами для закрытия моего приложения?
В основном у меня есть основная форма, которая при загрузке открывает дочернюю форму для входа в систему пользователя. Когда они отменяют или закрывают эту форму для входа, мне нужно закрыть все приложение.
Но, похоже, существует несколько способов закрыть программу С#:
-
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();