none
Application.Exit() ne sort pas de l'application? RRS feed

  • Question

  • Bonjour,

    Lorsque je roule une application et que j'utilise Application.Exit(), la fenêtre principale disparaît mais l'application continue de rouler.  Cette condition est présente dans une fenêtre particulière seulement.  Dans les autres, l'application quitte normalement sans rouler en arriêre-plan.

    Est-ce qu'il y a un moyen de forcer la sortie de l'application?

    Quels sont les conditions de non-sortie?


    Luc Saucier

    mercredi 16 mai 2012 13:55

Réponses

  • Bonjour,

    Donc cette fenêtre doit sans doute annuler la sortie de l'appli. C'est d'ailleurs indiqué tout simplement dans la doc http://msdn.microsoft.com/fr-fr/library/ms157894(v=vs.110).aspx :

    Exit arrête toutes les boucles de messages en cours sur tous les threads et ferme toutes les fenêtres d'application. Elle ne force pas nécessairement la fermeture de l'application." et plus loin "Exit est retourné sans action supplémentaire."

    Donc il faudrait voir ce que fait cette fenêtre, si on a d'autres threads lancés etc...

    Personnellement, je préfère toujours terminer l'application en essayant d'arriver jusqu'à la dernière instruction de la procédure Main...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    mercredi 16 mai 2012 14:47
    Modérateur
  • une chose est sure c'est qu'il y'a des threads qui tourne encore sur votre application et qui empéche l’opération (EXIT) . je propose d'implémenter une méthode qui parcours tous les threads de l'application et d'y forcer un KILL( Abort ou join) . comme ça on est sur que la fermeture se fait normalement.
    mercredi 16 mai 2012 19:47
  • je dirais plutot que ça ressemble à ça :

    Process[] pProcess = System.Diagnostics.Process.GetProcessesByName("Myprocess.exe");
    
    foreach (Process p in pProcess) {p.Kill();}

    Mais comme richard là dit, faire un kill est plutôt une solution de dernière minute.

    Peut être il faut mieux gérer ses propres threads ou bien simplement attendre la fin du traitement en cours de réalisation par le thread ou même mettre des TimeOut pour ne pas avoir des thread qui plante et bloque toute l'application.


    jeudi 17 mai 2012 10:21
  • En regardant sur l'internet le code d'un autre programme, j'y ai découvert ma réponse:

    1. Utiliser une variable booléenne pour le statut de l'application.

    2. Dans ma bouche, valider le contenu de cette variable.

    Je dois m'habituer à penser en «Multi-Thread».  J'ai un bagage d'expérience important en langage C; qui s'exécute habituellement de façon sérielle.

    Merci pour toutes ces réponses.


    Luc Saucier

    jeudi 17 mai 2012 15:56

Toutes les réponses

  • Bonjour,

    Donc cette fenêtre doit sans doute annuler la sortie de l'appli. C'est d'ailleurs indiqué tout simplement dans la doc http://msdn.microsoft.com/fr-fr/library/ms157894(v=vs.110).aspx :

    Exit arrête toutes les boucles de messages en cours sur tous les threads et ferme toutes les fenêtres d'application. Elle ne force pas nécessairement la fermeture de l'application." et plus loin "Exit est retourné sans action supplémentaire."

    Donc il faudrait voir ce que fait cette fenêtre, si on a d'autres threads lancés etc...

    Personnellement, je préfère toujours terminer l'application en essayant d'arriver jusqu'à la dernière instruction de la procédure Main...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    mercredi 16 mai 2012 14:47
    Modérateur
  • une chose est sure c'est qu'il y'a des threads qui tourne encore sur votre application et qui empéche l’opération (EXIT) . je propose d'implémenter une méthode qui parcours tous les threads de l'application et d'y forcer un KILL( Abort ou join) . comme ça on est sur que la fermeture se fait normalement.
    mercredi 16 mai 2012 19:47
  • Est-ce que vous avez une proposition de code pour forcer la fermeture des thread par «KILL»?

    Luc Saucier

    mercredi 16 mai 2012 19:51
  • Faire un kill ressemble plus à un patch de dernière minute qu'à une véritable solution.

    Il faudrait d'abord savoir exactement d'ou provient votre problème. Si c'est effectivement un thread qui tourne et qui est actif (et dans ce cas, vous devriez le savoir car c'est votre appli qui a lancé ce thread), modifiez votre code pour le terminer vous même proprement.

    La solution proposé ressemble plus à Hulk essayant d'ouvrir une bouteille de champagne ;-)


    Richard Clark
    Consultant - Formateur .NET
    http://www.c2i.fr
    Depuis 1996: le 1er site .NET francophone

    jeudi 17 mai 2012 08:06
  • je dirais plutot que ça ressemble à ça :

    Process[] pProcess = System.Diagnostics.Process.GetProcessesByName("Myprocess.exe");
    
    foreach (Process p in pProcess) {p.Kill();}

    Mais comme richard là dit, faire un kill est plutôt une solution de dernière minute.

    Peut être il faut mieux gérer ses propres threads ou bien simplement attendre la fin du traitement en cours de réalisation par le thread ou même mettre des TimeOut pour ne pas avoir des thread qui plante et bloque toute l'application.


    jeudi 17 mai 2012 10:21
  • Le traitement que je fais peut être annulé ou assassiné avec «KILL» sans problème.  Le problème, c'est que j'utilise une fenêtre dans une fenêtre et que la fenêtre enfant semble ne pas se terminer lorsque la fenêtre parent génère un Application.Exit().  Je désire laisser l'option à l'usager de quitter avec le menu mais même avec un Application.Exit(), cette fenêtre intérieure semble ne pas être annulé mais celle parent l'est.  Donc je perd la fenêtre mais le traitement est encore en mémoire.  À noter que cette fenêtre intérieure est affiché sans bordure et agit visuellement comme si c'est la fenêtre parent qui fournit les éléments.  De cette façon, lorsque j'utilise des options de menus, la tâche est terminé pour la fenêtre parent mais la tâche enfant reste disponible.

    Donc si vous avez une solution élégante à me proposer, je vous écoute.  Sinon, le «KILL» brutal fera la job.

    Voici du code pour aider à la compréhension - La forme parent qui affiche la forme enfant passé en paramètre:

        private void ShowForm(Form form)
        {
          if (actualForm != null)
          {
            actualForm.Hide();
    
            this.Controls.Remove(actualForm);
          }
    
          form.TopLevel = false;
          form.FormBorderStyle = FormBorderStyle.None;
          form.AutoScroll = true;
          form.Location = new System.Drawing.Point(0, 45);
          form.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
          form.Size = new Size(this.Size.Width, this.Size.Height);
          form.Show();
    
          this.Controls.Add(form);
    
          actualForm = form;
        }

    Après réflexion, je viens de voir ce qui est possiblement le problème...

    Une forme utilisé n'attend pas sa sortie.  Donc l'exécution se termine de l'appel mais la forme est encore active.  Il y a une forme qui nécessite un post-traitement donc qui ne peut terminer la procédure.  Donc j'ai fait un traitement dans l'appel du menu du genre:

    // Gestion de la forme
    var _frmIntérieure = new frmIntérieure
    ShowForm(_frmIntérieure);
    
    // Attente de fermeture
    while (_frmIntérieure.estSortie == false)
    {
      Application.DoEvents();
      Thread.Sleep(10);
    }
    
    // Traitement final
    Post-Traitement();
    

    C'est la seule forme qui a ce genre de traitement. Et c'est lorsque je suis dans cette forme que le traitement reste en mémoire.  J'ai aussi besoin que le post-traitement soit dans la forme parent.

    Quels sont les solutions?

    1. Utiliser un 'delegate'.

    2. Faire un appel à la forme parent en mettant «Post-Traitement» public.

    3. Rendre les éléments dans la forme parent public et faire le traitement avec ces variables.

    J'aimerais avoir vos suggestions sur la boucle utilisé et les solutions à apporter.


    Luc Saucier



    • Modifié LucSaucierSILS jeudi 17 mai 2012 13:15 Ajout important pour blocage de Application.Exit
    jeudi 17 mai 2012 12:56
  • En regardant sur l'internet le code d'un autre programme, j'y ai découvert ma réponse:

    1. Utiliser une variable booléenne pour le statut de l'application.

    2. Dans ma bouche, valider le contenu de cette variable.

    Je dois m'habituer à penser en «Multi-Thread».  J'ai un bagage d'expérience important en langage C; qui s'exécute habituellement de façon sérielle.

    Merci pour toutes ces réponses.


    Luc Saucier

    jeudi 17 mai 2012 15:56