В чем разница между этими методами для закрытия моего приложения? - PullRequest
13 голосов
/ 27 августа 2010

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

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

  1. Application.Exit();

  2. Application.ExitThread();

  3. Environment.Exit(1);

  4. Process.GetCurrentProcess().Kill();

  5. SFTPClient.LDAPLoggedIn = false; Close();

РЕДАКТИРОВАТЬ: Извините, если это не ясно: Он устанавливает свойство в объекте контроллера, чтобы указать, чтоВход в систему не удался.После открытия дочерней формы я бы проверил это свойство в родительской форме, чтобы увидеть, должна ли программа продолжаться или нет.Это в основном переносит ответственность за выход из программы на родителя без исключения.

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

Я вижу, что есть два способа справиться с этим:

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

Любой из этих двухсчитается лучшей практикой?

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

ОБНОВЛЕНИЕ: Спасибо за ответы.Для тех, кто ищет этот вопрос в будущем и для любопытных людей, это было мое решение в конце:

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()

Ответы [ 4 ]

12 голосов
/ 27 августа 2010

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

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


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

См. Выше.


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


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


  • SFTPClient.LDAPLoggedIn = false; Close();

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


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

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

4 голосов
/ 27 августа 2010

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

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

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

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

2 голосов
/ 27 августа 2010

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

1 голос
/ 14 апреля 2011

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

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

this.DialogResult = DialogResult.OK;
this.Close();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...