Почему 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();
}

Пытаться Environment.Exit(exitCode),

Я пошел, хотя эта ситуация во многих случаях я использую 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;
        }


    }
Другие вопросы по тегам