Comment quitter correctement une application C #?

197

J'ai une application publiée en C #. Le problème ici est que chaque fois que je ferme le formulaire principal en cliquant sur le bouton de sortie rouge, il ferme le formulaire mais ne ferme pas l'application. J'ai découvert cela lorsque j'ai essayé d'arrêter l'ordinateur, espérant que l'application que je faisais fonctionnait correctement, puis j'ai été bombardée par de nombreuses fenêtres enfants avec lesquelles j'ai mis des MessageBoxalertes.

J'ai essayé Application.Exitmais il appelle toujours toutes les fenêtres et alertes enfant et je ne sais pas comment utiliser Environment.Exitet quel entier y mettre.

Soit dit en passant, chaque fois que mes formulaires appellent l' événement formclosedor form closing, je ferme l'application avec une this.Hide()fonction; Cela affecte-t-il le comportement actuel de ma candidature?

John Ernest Guadalupe
la source
2
Ne pas gérer FormClosed ou FormClosing
SLaks
1
Vous dites donc que vous ne cachez que les formulaires au lieu de les fermer ? C'est probablement la raison pour laquelle l'application ne se termine pas, elle a toujours des formulaires ouverts (masqués).
Xint0
Ensuite, je devrais remplacer tout ceci.Hide () par this.Close ()?
John Ernest Guadalupe
1
Vous n'avez pas besoin de Hide () ou Close ().
Henk Holterman
1
Publiez le code concernant les actions et événements Close.
Henk Holterman

Réponses:

329

Depuis MSDN:

Application.Exit

Informe toutes les pompes de messages qu'elles doivent se terminer, puis ferme toutes les fenêtres d'application une fois les messages traités. C'est le code à utiliser si vous avez appelé Application.Run (applications WinForms), cette méthode arrête toutes les boucles de message en cours d'exécution sur tous les threads et ferme toutes les fenêtres de l'application.

Environment.Exit

Met fin à ce processus et donne au système d'exploitation sous-jacent le code de sortie spécifié. Il s'agit du code à appeler lorsque vous utilisez l'application console.

Cet article, Application.Exit vs Environment.Exit , pointe vers une bonne astuce:

Vous pouvez déterminer si System.Windows.Forms.Application.Runa été appelé en vérifiant la System.Windows.Forms.Application.MessageLooppropriété. Si true, Run a été appelé et vous pouvez supposer qu'une application WinForms s'exécute comme suit.

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

Référence: Pourquoi Application.Exit ne fonctionnerait-il pas?

Furqan Safdar
la source
Cela m'a été très utile car j'avais une application WinForms qui avait un argument pour qu'elle puisse fonctionner en silence et n'a donc pas montré de formulaire. Lorsque le formulaire a été masqué, il Application.Exit()n'a pas pu quitter l'application, mais a Environment.Exit(1)fonctionné comme un charme.
Dib
5
La question ne mentionne pas la sortie en raison d'une erreur, le code de sortie doit donc être nul: Environment.Exit(0) toute valeur non nulle est censée être un code d'erreur spécifique à l'application qui pourrait être utilisé par un script pour prendre les mesures appropriées. (Il s'agit d'un nouveau code et d'une application WinForms, il est donc peu probable dans ce cas, mais bon à savoir pour quiconque écrit des outils de ligne de commande.)
YipYip
Environment.Exitpeut également être utilisé pour l'application de formulaires.
Badiparmagi
1
Corrigez-moi si je me trompe, mais je pense qu'une returndéclaration ultérieure améliorerait beaucoup cette approche. Si j'ai bien compris, le code continuera son exécution après Application.Exit()une returndéclaration.
Bighted19
17

Je sais que ce n'est pas le problème que vous avez rencontré, mais une autre raison pour laquelle cela peut arriver est que vous avez un thread non d'arrière-plan ouvert dans votre application.

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

Quand IsBackgroundest falseil gardera votre programme ouvert jusqu'à ce que les finalise de fil, si vous définissez IsBackgroundau truefil ne sera pas garder ouvert le programme. Des choses comme BackgroundWoker, ThreadPoolet Tasktous utilisent en interne un thread avec IsBackgroundset to true.

Scott Chamberlain
la source
14

Tout ce dont tu as besoin c'est System.Environment.Exit(1);

Et il utilise l'espace de noms système "using System" qui est à peu près toujours là lorsque vous démarrez un projet.

Omar Moodie
la source
2
Son plus approprié aux applications de console uniquement.
Nidhin David
Une chose à noter est que les événements FormClosing / FormClosed ne seront pas appelés pour Environment.Exit également exitCode ne devrait être différent de zéro qu'en cas d'erreur,
Raphael Smit
9

Je voudrais soit l'un des suivants:

Application.Exit ();

pour un winform ou

Environment.Exit (0);

pour une application console (fonctionne aussi sur les winforms).

Merci!

Techcraft7
la source
Environment.Exit (0) fonctionne aussi pour WinForms, existe l'application sans lever aucune exception.
MulleOne
8

Au fait. chaque fois que mes formulaires appellent l'événement formclosed ou form closing, je ferme l'appliation avec une fonction this.Hide (). Cela affecte-t-il le comportement actuel de ma demande?

Bref, oui. L'application entière se terminera lorsque le formulaire principal (le formulaire démarré via Application.Rundans la Mainméthode) sera fermé (non masqué).

Si votre application entière doit toujours se terminer complètement chaque fois que votre formulaire principal est fermé, vous devez simplement supprimer ce gestionnaire fermé de formulaire. En n'annulant pas cet événement et en le laissant se fermer lorsque l'utilisateur le ferme, vous obtiendrez le comportement souhaité. Comme pour tous les autres formulaires, si vous n'avez pas l'intention de montrer à nouveau la même instance du formulaire, vous les laissez simplement se fermer, plutôt que d'empêcher la fermeture et de les masquer. Si vous les montrez à nouveau, alors les cacher peut être bien.

Si vous voulez que l'utilisateur puisse cliquer sur le "x" de votre formulaire principal, mais qu'un autre formulaire reste ouvert et, en fait, devienne le "nouveau" formulaire principal, alors c'est un peu plus compliqué. Dans un tel cas, vous devrez simplement masquer votre formulaire principal plutôt que de le fermer, mais vous devrez ajouter une sorte de mécanisme qui fermera réellement le formulaire principal lorsque vous voulez vraiment que votre application se termine. Si c'est la situation dans laquelle vous vous trouvez, vous devrez ajouter plus de détails à votre question décrivant quels types d'applications doivent et ne doivent pas réellement mettre fin au programme.

Servy
la source
3

Est ce que tu fais:

Application.Run(myForm);

dans votre Main ()?

J'ai trouvé que c'était un moyen très simple de tuer l'application lorsque le formulaire était fermé.

LightStriker
la source
1
oui, il a Application.Run dans le fichier Program.cs dans Main. Que dois-je faire pour le fermer alors?
John Ernest Guadalupe
Mais vous passez votre formulaire principal à Run, non? Le formulaire que vous fermez en cliquant sur le X rouge.
LightStriker
oui je l'ai monsieur. C'est comme ça: Application.Run (new Form2 ());
John Ernest Guadalupe
Dans ce cas, si le formulaire principal transmis à Run était vraiment complètement fermé, l'application se fermerait automatiquement. Vous devez ensuite savoir pourquoi ce formulaire est toujours ouvert, en cours d'exécution ou masqué quelque part.
LightStriker
3
Environment.Exit(exitCode); //exit code 0 is a proper exit and 1 is an error
joe pelletier
la source
-4

Dans ce cas, la façon la plus appropriée de quitter l'application pour remplacer la méthode onExit () dans App.xaml.cs:

protected override void OnExit(ExitEventArgs e) {
    base.OnExit(e); 
}
Anton Tsches
la source
Cela vous permet d'exécuter du code chaque fois qu'un événement de sortie se produit, mais ne provoque pas réellement l'événement de sortie.
jpaugh