Wie kann ich eine C # -Anwendung ordnungsgemäß beenden?

196

Ich habe eine veröffentlichte Anwendung in C #. Das Problem hierbei ist, dass jedes Mal, wenn ich das Hauptformular durch Klicken auf die rote Schaltfläche zum Beenden schließe, das Formular geschlossen wird, die Anwendung jedoch nicht geschlossen wird. Ich fand dies heraus, als ich versuchte, den Computer herunterzufahren, in der Hoffnung, dass die von mir erstellte Anwendung reibungslos lief, und wurde dann von vielen untergeordneten Fenstern bombardiert, mit denen ich MessageBoxWarnungen erstellt habe.

Ich habe es versucht, Application.Exitaber es werden immer noch alle untergeordneten Fenster und Warnungen aufgerufen, und ich weiß nicht, wie Environment.Exitund welche Ganzzahl ich verwenden soll.

Übrigens, wenn meine Formulare das Ereignis formclosedoder aufrufen, form closingschließe ich die Anwendung mit einer this.Hide()Funktion. Hat das Auswirkungen darauf, wie sich meine Anwendung jetzt verhält?

John Ernest Guadalupe
quelle
2
Behandeln Sie nicht FormClosed oder FormClosing
SLaks
1
Sie sagen also, Sie verstecken nur die Formulare, anstatt sie zu schließen ? Dies ist wahrscheinlich der Grund, warum die Anwendung nicht beendet wird. Sie hat immer noch offene (versteckte) Formulare.
Xint0
Dann sollte ich all das ersetzen. Hide () to this.Close ()?
John Ernest Guadalupe
1
Sie brauchen weder Hide () noch Close ().
Henk Holterman
1
Veröffentlichen Sie den Code zum Schließen von Aktionen und Ereignissen.
Henk Holterman

Antworten:

329

Von MSDN:

Application.Exit

Informiert alle Nachrichtenpumpen darüber, dass sie beendet werden müssen, und schließt dann alle Anwendungsfenster, nachdem die Nachrichten verarbeitet wurden. Dies ist der Code, der verwendet werden muss, wenn Sie Application.Run (WinForms-Anwendungen) aufgerufen haben. Diese Methode stoppt alle laufenden Nachrichtenschleifen in allen Threads und schließt alle Fenster der Anwendung.

Environment.Exit

Beendet diesen Prozess und gibt dem zugrunde liegenden Betriebssystem den angegebenen Exit-Code. Dies ist der Code, der aufgerufen werden muss, wenn Sie eine Konsolenanwendung verwenden.

Dieser Artikel, Application.Exit vs. Environment.Exit , weist auf einen guten Tipp hin:

Sie können feststellen, ob System.Windows.Forms.Application.Runaufgerufen wurde, indem Sie die System.Windows.Forms.Application.MessageLoopEigenschaft überprüfen . Wenn true, wurde Run aufgerufen, und Sie können davon ausgehen, dass eine WinForms-Anwendung wie folgt ausgeführt wird.

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

Referenz: Warum funktioniert Application.Exit nicht?

Furqan Safdar
quelle
Dies war sehr nützlich für mich, da ich eine WinForms-App hatte, die ein Argument hatte, damit sie lautlos ausgeführt werden konnte und daher kein Formular zeigte. Wenn das Formular ausgeblendet war, Application.Exit()konnte die App nicht beendet werden, Environment.Exit(1)funktionierte jedoch wie ein Zauber.
Dib
5
In der Frage wurde das Beenden aufgrund eines Fehlers nicht erwähnt, daher sollte der Beendigungscode Null sein: Environment.Exit(0) Jeder Wert ungleich Null ist ein anwendungsspezifischer Fehlercode, der von einem Skript verwendet werden kann, um geeignete Maßnahmen zu ergreifen. (Dies ist neuer Code und eine WinForms-Anwendung, daher ist es in diesem Fall unwahrscheinlich, aber für jeden, der Befehlszeilentools schreibt, gut zu wissen.)
YipYip
Environment.Exitkann auch für die Formularanwendung verwendet werden.
Badiparmagi
1
Korrigieren Sie mich, wenn ich falsch liege, aber ich denke, eine spätere returnAussage würde diesen Ansatz erheblich verbessern. Soweit ich verstanden habe, wird der Code nach Application.Exit()einer returnAnweisung weiter ausgeführt.
Bighted19
17

Ich weiß, dass dies nicht das Problem ist, das Sie hatten. Ein weiterer Grund dafür könnte sein, dass in Ihrer Anwendung ein Thread ohne Hintergrund offen ist.

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

Wann IsBackgroundist falsewird es Ihr Programm bis in dem Thread abgeschlossen ist offen zu halten, wenn Sie setzen IsBackgroundauf truedas Gewinde wird das Programm nicht offen halten. Dinge wie BackgroundWoker, ThreadPoolund Taskalle verwenden intern einen Thread mit IsBackgroundset to true.

Scott Chamberlain
quelle
14

Alles was Sie brauchen ist System.Environment.Exit(1);

Und es verwendet den System-Namespace "using System", der so ziemlich immer vorhanden ist, wenn Sie ein Projekt starten.

Omar Moodie
quelle
2
Es ist eher für Konsolenanwendungen geeignet.
Nidhin David
Eine Sache zu beachten ist, dass FormClosing / FormClosed-Ereignisse nicht für Environment aufgerufen werden. Exit auch exitCode sollte nur ungleich Null sein, wenn ein Fehler aufgetreten ist,
Raphael Smit
9

Ich würde eines der folgenden:

Application.Exit ();

für eine Winform oder

Environment.Exit (0);

für eine Konsolenanwendung (funktioniert auch mit Winforms).

Vielen Dank!

Techcraft7
quelle
Environment.Exit (0) funktioniert auch für WinForms, die Anwendung existiert ohne Ausnahme.
MulleOne
8

Apropos. Immer wenn meine Formulare das Ereignis formclosed oder form schließt, schließe ich die Anwendung mit der Funktion this.Hide (). Hat das Auswirkungen darauf, wie sich meine Anwendung jetzt verhält?

Kurz gesagt, ja. Die gesamte Anwendung wird beendet, wenn das Hauptformular (das über Application.Rundie MainMethode gestartete Formular ) geschlossen (nicht ausgeblendet) wird.

Wenn Ihre gesamte Anwendung immer vollständig beendet werden soll, wenn Ihr Hauptformular geschlossen wird, sollten Sie einfach diesen geschlossenen Handler für Formulare entfernen. Wenn Sie dieses Ereignis nicht abbrechen und es nur schließen lassen, wenn der Benutzer es schließt, erhalten Sie das gewünschte Verhalten. Wenn Sie bei allen anderen Formularen nicht beabsichtigen, dieselbe Instanz des Formulars erneut anzuzeigen, lassen Sie sie einfach schließen, anstatt das Schließen zu verhindern und sie auszublenden. Wenn Sie sie erneut anzeigen, ist es möglicherweise in Ordnung, sie auszublenden.

Wenn Sie möchten, dass der Benutzer auf das "x" für Ihr Hauptformular klickt, aber ein anderes Formular geöffnet bleibt und praktisch das "neue" Hauptformular wird, ist dies etwas komplizierter. In einem solchen Fall müssen Sie nur Ihr Hauptformular ausblenden, anstatt es zu schließen. Sie müssen jedoch einen Mechanismus hinzufügen, der das Hauptformular tatsächlich schließt, wenn Sie wirklich möchten, dass Ihre App endet. Wenn dies die Situation ist, in der Sie sich befinden, müssen Sie Ihrer Frage weitere Details hinzufügen, in denen beschrieben wird, welche Arten von Anwendungen das Programm tatsächlich beenden sollen und welche nicht.

Servieren
quelle
3

Machst du:

Application.Run(myForm);

in deinem Main ()?

Ich fand es eine sehr einfache Möglichkeit, die Anwendung zu beenden, wenn das Formular geschlossen wird.

LightStriker
quelle
1
Ja, Application.Run befindet sich in der Datei Program.cs in Main. Was mache ich dann, um es zu schließen?
John Ernest Guadalupe
Aber du gibst dein Hauptformular an Run weiter, oder? Das Formular schließen Sie durch Klicken auf das rote X.
LightStriker
Ja, ich habe es, Sir. Es ist wie folgt: Application.Run (neues Form2 ());
John Ernest Guadalupe
In diesem Fall würde die Anwendung automatisch beendet, wenn das an Run übergebene Hauptformular wirklich vollständig geschlossen wäre. Sie müssen dann nachverfolgen, warum dieses Formular noch geöffnet, ausgeführt oder irgendwo versteckt ist.
LightStriker
3
Environment.Exit(exitCode); //exit code 0 is a proper exit and 1 is an error
Joe Pelletier
quelle
-4

In diesem Fall ist der beste Weg, die Anwendung zu beenden, um die onExit () -Methode in App.xaml.cs zu überschreiben:

protected override void OnExit(ExitEventArgs e) {
    base.OnExit(e); 
}
Anton Tsches
quelle
Auf diese Weise können Sie Code ausführen, wenn ein Exit-Ereignis eintritt, das Exit-Ereignis jedoch nicht.
Jpaugh