Как правильно выйти из приложения C #?

198

У меня есть опубликованное приложение на C #. Проблема здесь в том, что всякий раз, когда я закрываю основную форму, нажимая на красную кнопку выхода, она закрывает форму, но не закрывает приложение. Я узнал об этом, когда попытался выключить компьютер, надеясь, что приложение, которое я создал, работало без сбоев, а затем я был засыпан множеством дочерних окон, с которыми я установил MessageBoxоповещения.

Я пытался, Application.Exitно он по-прежнему вызывает все дочерние окна и оповещения, и я не знаю, как использовать Environment.Exitи какое целое число вставить в него.

Кстати, всякий раз, когда мои формы вызывают событие formclosedили, form closingя закрываю приложение с помощью this.Hide()функции; Влияет ли это на поведение моего приложения сейчас?

Джон Эрнест Гуадалупе
источник
2
Не работайте с FormClosed или FormClosing
SLaks
1
То есть вы говорите, что скрываете только формы, а не закрываете их? Это, вероятно, причина, по которой приложение не закрывается, оно все еще имеет открытые (скрытые) формы.
Xint0
Тогда я должен заменить все это.Скрыть () на это. Закрыть ()?
Джон Эрнест Гуадалупе
1
Вам не нужно Скрыть () или Закрыть ().
Хенк Холтерман
1
Разместите код, касающийся действий и событий Close.
Хенк Холтерман

Ответы:

330

Из MSDN:

Application.Exit

Информирует все рассылки сообщений о том, что они должны прекратить работу, а затем закрывает все окна приложений после обработки сообщений. Этот код используется, если вы вызвали Application.Run (приложения WinForms), этот метод останавливает все выполняющиеся циклы сообщений во всех потоках и закрывает все окна приложения.

Environment.Exit

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

Эта статья, Application.Exit vs. Environment.Exit , указывает на хороший совет:

Вы можете определить System.Windows.Forms.Application.Run, был ли вызван, проверив System.Windows.Forms.Application.MessageLoopсвойство. Если true, то был вызван Run, и вы можете предположить, что приложение WinForms выполняется следующим образом.

if (System.Windows.Forms.Application.MessageLoop) 
{
    // WinForms app
    System.Windows.Forms.Application.Exit();
}
else
{
    // Console app
    System.Environment.Exit(1);
}

Ссылка: Почему Application.Exit не работает?

Фуркан Сафдар
источник
Это было очень полезно для меня, так как у меня было приложение WinForms, у которого был аргумент, чтобы оно могло работать без вывода сообщений и, следовательно, не показывало форму. Когда форма была скрыта, то Application.Exit()не смогла выйти из приложения, однако Environment.Exit(1)работала как шарм.
Диб
5
В вопросе не упоминалось завершение из-за ошибки, поэтому код выхода должен быть нулевым: Environment.Exit(0) любое ненулевое значение подразумевает код ошибки конкретного приложения, который может использоваться сценарием для выполнения соответствующих действий. (Это новый код и приложение WinForms, так что в этом случае это вряд ли имеет значение, но это полезно знать всем, кто пишет инструменты командной строки.)
YipYip
Environment.Exitможно использовать и для применения форм.
Badiparmagi
1
Поправьте меня, если я ошибаюсь, но я думаю, что returnзаявление впоследствии улучшит этот подход. Как я понял код будет продолжать выполнение после Application.Exit()до в returnзаявлении.
Bighted19
17

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

using System;
using System.Threading;
using System.Windows.Forms;

namespace Sandbox_Form
{
    static class Program
    {
        private static Thread thread;

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            thread = new Thread(BusyWorkThread);
            thread.IsBackground = false;
            thread.Start();

            Application.Run(new Form());

        }

        public static void BusyWorkThread()
        {
            while (true)
            {
                Thread.Sleep(1000);
            }
        }
    }
}

Когда IsBackgroundэто falseбудет держать вашу программу открыты до резьбы Завершает, если вы установите IsBackgroundна trueрезьбу не будет держать программу открытой. Такие вещи, как BackgroundWoker, ThreadPoolи Taskвсе внутренне используют поток с IsBackgroundустановленным на true.

Скотт Чемберлен
источник
14

Все, что тебе нужно System.Environment.Exit(1);

И он использует системное пространство имен «using System», которое почти всегда присутствует при запуске проекта.

Омар Муди
источник
2
Его больше подходит только для консольных приложений.
Нидин Дэвид
Следует отметить, что события FormClosing / FormClosed не будут вызываться для Environment.Exit, а также exitCode должен быть ненулевым, если произошла ошибка,
Raphael Smit
10

Я бы выбрал одно из следующих:

Application.Exit ();

для формы или

Environment.Exit (0);

для консольного приложения (работает также на winforms).

Спасибо!

Techcraft7
источник
Environment.Exit (0) также работает для WinForms, существует приложение без каких-либо исключений.
MulleOne
8

Кстати. всякий раз, когда мои формы вызывают событие formclosed или закрытия формы, я закрываю приложение с помощью функции this.Hide (). Влияет ли это на поведение моего приложения сейчас?

Короче да. Все приложение закончится, когда основная форма (форма, запущенная Application.Runв Mainметоде) будет закрыта (не скрыта).

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

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

Servy
источник
3

Вы делаете:

Application.Run(myForm);

в вашем главном ()?

Я нашел очень простой способ убить приложение, когда форма закрыта.

LightStriker
источник
1
да, он имеет Application.Run в файле Program.cs в Main. Что мне делать, чтобы закрыть его тогда?
Джон Эрнест Гуадалупе
Но вы передаете свою основную форму Run, верно? Форма, которую вы закрываете, нажимая на красный
крестик.
да, у меня есть, сэр. Это так: Application.Run (new Form2 ());
Джон Эрнест Гуадалупе
В этом случае, если основная форма, переданная Run, была действительно полностью закрыта, приложение автоматически закрывалось. Затем вы должны отследить, почему эта форма еще где-то открыта, работает или скрыта.
LightStriker
3
Environment.Exit(exitCode); //exit code 0 is a proper exit and 1 is an error
Джо Пеллетье
источник
-4

В этом случае наиболее подходящий способ выхода из приложения - переопределить метод onExit () в App.xaml.cs:

protected override void OnExit(ExitEventArgs e) {
    base.OnExit(e); 
}
Антон Чес
источник
Это позволяет вам выполнять код всякий раз, когда происходит событие выхода, но фактически не вызывает событие выхода.
jpaugh