Como sair corretamente de um aplicativo C #?


197

Eu tenho um aplicativo publicado em c #. O problema aqui é que sempre que fecho o formulário principal, clicando no botão vermelho de saída, ele fecha o formulário, mas não fecha o aplicativo. Descobri isso quando tentei desligar o computador, esperançoso de que o aplicativo que fiz estava funcionando sem problemas e fui bombardeado por muitas janelas filho com as quais coloquei MessageBoxalertas.

Eu tentei, Application.Exitmas ele ainda chama todas as janelas e alertas filhos e não sei como usar Environment.Exite qual número inteiro colocar nele.

A propósito, sempre que meus formulários chamam o evento formclosedou form closing, eu fecho o aplicativo com uma this.Hide()função; Isso afeta o comportamento do meu aplicativo agora?


2
Não manipule FormClosed ou FormClosing
SLaks

1
Então você diz que está apenas ocultando os formulários em vez de fechá- los? Essa é provavelmente a razão pela qual o aplicativo não está sendo finalizado, ele ainda possui formulários abertos (ocultos).
Xint0

Então, eu deveria substituir tudo isso. Hide () to this.Close ()?
John Ernest Guadalupe

1
Você não precisa de Hide () ou Close ().
Henk Holterman

1
Publique o código referente a ações e eventos de fechamento.
Henk Holterman

Respostas:


329

Do MSDN:

Application.Exit

Informa a todas as bombas de mensagens que elas devem terminar e, em seguida, fecha todas as janelas do aplicativo após o processamento das mensagens. Esse é o código a ser usado se você tiver chamado Application.Run (aplicativos WinForms), esse método interrompe todos os loops de mensagens em execução em todos os segmentos e fecha todas as janelas do aplicativo.

Environment.Exit

Finaliza esse processo e fornece ao sistema operacional subjacente o código de saída especificado. Este é o código a ser chamado quando você estiver usando o aplicativo de console.

Este artigo, Application.Exit vs. Environment.Exit , aponta para uma boa dica:

Você pode determinar se System.Windows.Forms.Application.Runfoi chamado verificando a System.Windows.Forms.Application.MessageLooppropriedade Se verdadeiro, então Executar foi chamado e você pode assumir que um aplicativo WinForms está executando da seguinte maneira.

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

Referência: Por que Application.Exit falharia ao funcionar?


Isso foi realmente útil para mim, pois eu tinha um aplicativo WinForms que tinha um argumento para que pudesse ser executado silenciosamente e, portanto, não mostrava um formulário. Quando o formulário estava oculto, Application.Exit()falhava ao sair do aplicativo, mas Environment.Exit(1)funcionava como um encanto.
Dib

5
A pergunta não mencionou a saída devido a um erro; portanto, o código de saída deve ser zero: Environment.Exit(0) qualquer valor diferente de zero deve ser um código de erro específico do aplicativo que pode ser usado por um script para executar as ações apropriadas. (Este é o novo código e um aplicativo WinForms, por isso é improvável que importa neste caso, mas bom saber para ferramentas de linha de comando qualquer escrita.)
YipYip

Environment.Exittambém pode ser usado para aplicação de formulários.
Badiparmagi 22/02/19

1
Corrija-me se estiver errado, mas acho que uma returndeclaração posterior melhoraria muito essa abordagem. Pelo que entendi, o código continuaria a execução após Application.Exit()até uma returndeclaração.
Bighted19

17

Sei que esse não foi o problema que você teve, mas outro motivo para isso acontecer é que você tem um thread não em segundo plano aberto no seu aplicativo.

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);
            }
        }
    }
}

Quando IsBackgroundé falseque vai manter o seu programa aberto até as concluída fio, se você definir IsBackgroundpara trueo segmento não vai manter o programa aberto. Coisas como BackgroundWoker, ThreadPoole Tasktodos usam internamente um fio com IsBackgroundconjunto para true.


14

Tudo o que você precisa é System.Environment.Exit(1);

E ele usa o espaço para nome do sistema "using System", que quase sempre existe quando você inicia um projeto.


2
É mais adequado apenas para aplicativos de console.
Nidhin David

Uma coisa a notar é FormClosing / eventos FormClosed não será chamado para Environment.Exit também exitCode só deve ser diferente de zero se um erro ocorreu,
Raphael Smit

9

Gostaria de um dos seguintes:

Application.Exit ();

para um winform ou

Environment.Exit (0);

para um aplicativo de console (funciona também em winforms).

Obrigado!


Environment.Exit (0) também funciona para WinForms, existe o aplicativo sem gerar nenhuma exceção.
MulleOne

8

A propósito. sempre que meus formulários chamam o evento formclosed ou encerramento de formulário, fecho a aplicação com uma função this.Hide (). Isso afeta o comportamento do meu aplicativo agora?

Em suma, sim. O aplicativo inteiro será encerrado quando o formulário principal (o formulário iniciado Application.Runno Mainmétodo) for fechado (não oculto).

Se todo o seu aplicativo sempre deve terminar totalmente sempre que o formulário principal for fechado, remova o manipulador fechado desse formulário. Ao não cancelar esse evento e deixá-lo fechar quando o usuário o fechar, você obterá o comportamento desejado. Quanto a todos os outros formulários, se você não pretende mostrar a mesma instância do formulário novamente, basta deixá-los fechar, em vez de impedir o fechamento e a ocultação. Se você estiver exibindo-os novamente, é possível escondê-los.

Se você deseja que o usuário clique no "x" do formulário principal, mas mantenha outro formulário aberto e, com efeito, torne-se o "novo" formulário principal, é um pouco mais complicado. Nesse caso, você precisará apenas ocultar seu formulário principal em vez de fechá-lo, mas precisará adicionar algum tipo de mecanismo que realmente feche o formulário principal quando você realmente deseja que seu aplicativo termine. Se você estiver nessa situação, precisará adicionar mais detalhes à sua pergunta, descrevendo quais tipos de aplicativos devem ou não encerrar o programa.


3

Você faz:

Application.Run(myForm);

no seu Main ()?

Eu achei uma maneira muito fácil de matar o aplicativo quando o formulário é fechado.


1
sim, ele possui Application.Run no arquivo Program.cs no Main. O que eu faço para fechá-lo então?
John Ernest Guadalupe

Mas você passa seu formulário principal para Executar, certo? Para fechar o formulário, clique no X vermelho.
LightStriker

sim eu tenho senhor. É assim: Application.Run (new Form2 ());
John Ernest Guadalupe

Nesse caso, se o formulário principal passado para Executar fosse totalmente totalmente fechado, o aplicativo sairia automaticamente. Você deve acompanhar por que esse formulário ainda está aberto, em execução ou oculto em algum lugar.
LightStriker

3
Environment.Exit(exitCode); //exit code 0 is a proper exit and 1 is an error

-4

Nesse caso, a maneira mais adequada de sair do aplicativo para substituir o método onExit () no App.xaml.cs:

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

Isso permite que você execute o código sempre que um evento de saída acontece, mas na verdade não causa o evento de saída.
jpaugh
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.