Почему Application.Exit не работает?
У меня есть приложение, которое получало странные ошибки при отмене из диалогового окна. Приложение не может продолжить работу, если окно отменено, поэтому оно закрывается, но по какой-то причине оно не работает и, следовательно, продолжает работать и вылетает.
Я отладил эту проблему, и каким-то образом приложение запускается сразу после вызова Application.Exit. Я работаю в режиме отладки, и это актуально из-за небольшого объема кода, который зависит от определяемой переменной RELEASE. Вот код выхода моего приложения. Я проследил код, и он вошел в метод ExitApp и продолжает идти, возвращая управление вызывающей стороне и в конечном итоге сбой.
Это приложение, которое предоставляет отчеты по подключению к удаленному рабочему столу, поэтому код выхода немного странный. Он пытается завершить удаленный сеанс, но только при запуске под выпуском, потому что я не хочу выключать свою машину разработчика при каждом запуске теста.
private void ExitApp()
{
HardTerminalExit();
Application.Exit();
}
// When in Debug mode running on a development computer, this will not run to avoid shutting down the dev computer
// When in release mode the Remote Connection or other computer this is run on will be shut down.
[Conditional("RELEASE")]
private void HardTerminalExit()
{
WTSLogoffSession(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, false);
}
Я запустил отладчик сразу за строкой Application.Exit, и ничего не происходит, а затем элемент управления возвращается к вызывающей программе после того, как я прошёл эту строку.
В чем дело? Это приложение Windows Forms.
10 ответов
Эта статья расширяет ту же цепочку мыслей, которую вы проходите: http://www.dev102.com/2008/06/24/how-do-you-exit-your-net-application/
В принципе:
Environment.Exit - из MSDN: завершает этот процесс и предоставляет базовой операционной системе указанный код выхода. Это код для вызова, когда вы используете консольное приложение.
Application.Exit - из MSDN: сообщает всем обработчикам сообщений, что они должны прекратить работу, а затем закрывает все окна приложений после обработки сообщений. Этот код используется, если вы вызвали Application.Run (приложения WinForms), этот метод останавливает все выполняющиеся циклы сообщений во всех потоках и закрывает все окна приложения. Есть еще несколько проблем с этим методом, читайте об этом на странице MSDN.
Еще одно обсуждение этого: http://geekswithblogs.net/mtreadwell/archive/2004/06/06/6123.aspx
Эта статья указывает на хороший совет:
Вы можете определить, был ли вызван System.Windows.Forms.Application.Run, проверив свойство System.Windows.Forms.Application.MessageLoop. Если true, тогда был вызван Run, и вы можете предположить, что приложение WinForms выполняется следующим образом.
if (System.Windows.Forms.Application.MessageLoop)
{
// Use this since we are a WinForms app
System.Windows.Forms.Application.Exit();
}
else
{
// Use this since we are a console app
System.Environment.Exit(1);
}
Недавно столкнувшись с этой проблемой (из-за того, что Application.Exit не удалось правильно завершить рассылку сообщений для win-форм с помощью Application.Run(new Form())), я обнаружил, что если вы порождаете новые потоки или запускаете фоновые рабочие в конструкторе, это предотвратит запуск Application.Exit.
Переместите все вызовы RunWorkerAsync из конструктора в метод Load формы:
public Form()
{
this.Worker.RunWorkerAsync();
}
Переместить в:
public void Form_Load(object sender, EventArgs e)
{
this.Worker.RunWorkerAsync();
}
Я пошел, хотя эта ситуация во многих случаях я использую Thread.CurrentThread.Abort()
и процесс закрыт. Кажется, что Application.Exit не соединяется с текущим потоком должным образом.
Убедитесь, что у вас нет Console.ReadLine(); в вашем приложении и Environment.Exit(1); будет работать и закрыть ваше приложение.
Также убедитесь, что для всех потоков, запущенных в вашем приложении, для свойства IsBackground установлено значение true. Не фоновые потоки легко блокируют выход приложения.
Я создал следующее, что позволит выйти из приложения в любом месте. Вам не нужно беспокоиться, запущена форма или нет, тест определяет это и вызывает соответствующий Exit.
public void exit(int exitCode)
{
if (System.Windows.Forms.Application.MessageLoop)
{
// Use this since we are a WinForms app
System.Windows.Forms.Application.Exit()
}
else
{
// Use this since we are a console app
System.Environment.Exit(exitCode);
}
} //* end exit()
Это приложение запущено (в Main
метод) с помощью Application.Run()
? Иначе, Application.Exit()
не сработает
Если вы написали свой собственный Main
метод, и вы хотите остановить приложение, вы можете остановить только вернувшись из Main
метод (или убивает процесс).
Попробуй это:
в файле Program.cs:
после Application.Run(новая форма ());
добавить Application.Exit();
private void frmLogin_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
DialogResult result = MessageBox.Show("Do you really want to exit?", "Dialog Title", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
Environment.Exit(0);
}
else
{
e.Cancel = true;
}
}
else
{
e.Cancel = true;
}
}