Come uscire correttamente da un'applicazione C #?


198

Ho un'applicazione pubblicata in C #. Il problema qui è ogni volta che chiudo il modulo principale facendo clic sul pulsante di uscita rosso, chiude il modulo ma non chiude l'applicazione. L'ho scoperto quando ho provato a spegnere il computer, sperando che l'applicazione che ho realizzato funzionasse senza problemi, quindi sono stato bombardato da molte finestre secondarie con cui ho inserito gli MessageBoxavvisi.

Ho provato Application.Exitma chiama ancora tutte le finestre secondarie e gli avvisi e non so come utilizzare Environment.Exite quale numero intero inserire.

A proposito, ogni volta che i miei moduli chiamano l' evento formclosedo form closingchiudo l'applicazione con una this.Hide()funzione; Ciò influisce sul comportamento della mia applicazione ora?


2
Non gestire FormClosed o FormClosing
SLaks

1
Quindi dici di nascondere solo i moduli invece di chiuderli ? Questo è probabilmente il motivo per cui l'applicazione non viene chiusa, ha ancora moduli aperti (nascosti).
Xint0

Quindi dovrei sostituire tutto questo this.Hide () a this.Close ()?
John Ernest Guadalupe,

1
Non hai bisogno di Hide () o Close ().
Henk Holterman,

1
Pubblica il codice relativo alle azioni e agli eventi vicini.
Henk Holterman,

Risposte:


330

Da MSDN:

Application.Exit

Informa tutti i pump dei messaggi che devono terminare, quindi chiude tutte le finestre dell'applicazione dopo l'elaborazione dei messaggi. Questo è il codice da utilizzare se si è chiamato Application.Run (applicazioni WinForms), questo metodo interrompe tutti i cicli di messaggi in esecuzione su tutti i thread e chiude tutte le finestre dell'applicazione.

Environment.Exit

Termina questo processo e fornisce al sistema operativo sottostante il codice di uscita specificato. Questo è il codice da chiamare quando si utilizza l'applicazione console.

Questo articolo, Application.Exit vs. Environment.Exit , punta verso un buon consiglio:

È possibile determinare se System.Windows.Forms.Application.Runè stato chiamato controllando la System.Windows.Forms.Application.MessageLoopproprietà. Se vero, allora Run è stato chiamato e si può presumere che un'applicazione WinForms stia eseguendo come segue.

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

Riferimento: Perché Application.Exit non funzionerebbe?


Questo è stato davvero utile per me dato che avevo un'app WinForms che aveva un argomento in modo che potesse funzionare silenziosamente e quindi non mostrasse un modulo. Quando il modulo è stato nascosto, Application.Exit()non è riuscito a uscire dall'app, tuttavia ha Environment.Exit(1)funzionato come un fascino.
Data

5
La domanda non menzionava l'uscita a causa di un errore, quindi il codice di uscita dovrebbe essere zero: Environment.Exit(0) qualsiasi valore diverso da zero deve essere un codice di errore specifico dell'applicazione che potrebbe essere utilizzato da uno script per eseguire l'azione appropriata. (Questo è un nuovo codice e un'applicazione WinForms, quindi è improbabile che contenga in questo caso, ma è utile conoscerlo per chiunque
stia

Environment.Exitpuò essere utilizzato anche per l'applicazione di moduli.
Badiparmagi,

1
Correggimi se sbaglio, ma penso che una returndichiarazione in seguito migliorerebbe molto questo approccio. Come ho capito, il codice avrebbe continuato l'esecuzione dopo Application.Exit()una returndichiarazione.
Bighted19

17

So che questo non è il problema che hai avuto, tuttavia un altro motivo potrebbe accadere è che nella tua applicazione è aperto un thread non in background.

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è falseche manterrà il vostro programma aperto fino al completamento del filo, se si imposta IsBackgroundper trueil thread non mancherà di tenere il programma aperto. Cose come BackgroundWoker, ThreadPoole Tasktutti usano internamente un thread con IsBackgroundset su true.


14

Tutto ciò che serve è System.Environment.Exit(1);

E utilizza lo spazio dei nomi di sistema "using System" che è praticamente sempre lì quando si avvia un progetto.


2
È più adatto solo per applicazioni console.
Nidhin David,

Una cosa da notare è che gli eventi FormClosing / FormClosed non verranno chiamati per Environment.Exit inoltre exitCode dovrebbe essere diverso da zero se si è verificato un errore,
Raphael Smit

10

Vorrei uno dei seguenti:

Application.Exit ();

per una forma di win o

Environment.Exit (0);

per un'applicazione console (funziona anche su winforms).

Grazie!


Environment.Exit (0) funziona anche per WinForms, esiste l'applicazione senza generare alcuna eccezione.
MulleOne,

8

A proposito. ogni volta che i miei moduli chiamano il formclosed o l'evento di chiusura del modulo chiudo l'applicciation con una funzione this.Hide (). Ciò influisce sul comportamento della mia applicazione ora?

Insomma sì. L'intera applicazione termina quando il modulo principale (il modulo avviato tramite Application.Runnel Mainmetodo) viene chiuso (non nascosto).

Se l'intera applicazione deve sempre terminare completamente ogni volta che il modulo principale viene chiuso, è sufficiente rimuovere quel gestore chiuso del modulo. Non annullando quell'evento e lasciandolo semplicemente chiudere quando l'utente lo chiude otterrai il comportamento desiderato. Come per tutte le altre forme, se non hai intenzione di mostrare di nuovo quella stessa istanza del modulo, devi solo lasciarli chiudere, piuttosto che impedire la chiusura e nasconderli. Se le stai mostrando di nuovo, nasconderle potrebbe andare bene.

Se vuoi essere in grado di fare in modo che l'utente faccia clic sulla "x" per il modulo principale, ma fai in modo che un altro modulo rimanga aperto e, in effetti, diventi il ​​"nuovo" modulo principale, quindi è un po 'più complicato. In tal caso, dovrai semplicemente nascondere il modulo principale anziché chiuderlo, ma dovrai aggiungere una sorta di meccanismo che chiuderà effettivamente il modulo principale quando vuoi davvero che la tua app finisca. Se questa è la situazione in cui ti trovi, dovrai aggiungere ulteriori dettagli alla tua domanda descrivendo quali tipi di applicazioni dovrebbero e non dovrebbero effettivamente terminare il programma.


3

Fai:

Application.Run(myForm);

nel tuo Main ()?

Ho trovato un modo molto semplice per terminare l'applicazione quando il modulo è chiuso.


1
sì, ha Application.Run nel file Program.cs in Main. Cosa devo fare per chiuderlo allora?
John Ernest Guadalupe,

Ma passi il modulo principale a Run, giusto? Il modulo che chiudi facendo clic sulla X rossa.
LightStriker

si ce l'ho signore. È così: Application.Run (new Form2 ());
John Ernest Guadalupe,

In tal caso, se il modulo principale passato a Esegui fosse veramente completamente chiuso, l'applicazione verrebbe automaticamente chiusa. È quindi necessario tenere traccia del motivo per cui quel modulo è ancora aperto, in esecuzione o nascosto da qualche parte.
LightStriker,

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

-4

In questo caso, il modo più corretto per chiudere l'applicazione per sovrascrivere il metodo onExit () in App.xaml.cs:

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

Ciò consente di eseguire il codice ogni volta che si verifica un evento di uscita, ma in realtà non provoca l'evento di uscita.
jpaugh,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.