Как правильно выйти из приложения 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).

Спасибо!


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

8

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

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

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

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


3

Вы делаете:

Application.Run(myForm);

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

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


1
да, он имеет Application.Run в файле Program.cs в Main. Что мне делать, чтобы закрыть его тогда?
Джон Эрнест Гуадалупе

Но вы передаете свою основную форму Run, верно? Форма, которую вы закрываете, нажимая на красный
крестик.

да, у меня есть, сэр. Это так: Application.Run (new Form2 ());
Джон Эрнест Гуадалупе

В этом случае, если основная форма, переданная Run, была действительно полностью закрыта, приложение автоматически закрывалось. Затем вы должны отследить, почему эта форма еще где-то открыта, работает или скрыта.
LightStriker


-4

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

protected override void OnExit(ExitEventArgs e) {
    base.OnExit(e); 
}

Это позволяет вам выполнять код всякий раз, когда происходит событие выхода, но фактически не вызывает событие выхода.
jpaugh
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.