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?

John Ernest Guadalupe
fonte
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?

Furqan Safdar
fonte
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.

Scott Chamberlain
fonte
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.

Omar Moodie
fonte
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!

Techcraft7
fonte
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.

Servy
fonte
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.

LightStriker
fonte
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
joe pelletier
fonte
-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); 
}
Anton Tsches
fonte
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