2009-06-30 9 views
3

J'ai une application que je remets en marche à 2 heures tous les matins en utilisantcomment puis-je redémarrer une seule instance WinForms demande

Application.Restart();

le problème est qu'une inspection quelques semaines plus tard montre qu'il ya 6 ou alors les instances en cours d'exécution.

J'ai essayé de limiter le nombre d'instances en utilisant

bool IsOwned; 
Mutex m = new Mutex(true, Name, out IsOwned); 
if (!IsOwned) 
     Environment.Exit(0); 

Mais cela ne fonctionne pas pour une raison quelconque, récemment arrêté par exemple était encore visible ... ou du moins c'est mon interprétation et comme résultat que l'application n'a pas réagi.

Où est-ce que je me suis trompé?

Répondre

3

Assurez-vous que vous accrochez sur l'événement de sortie de l'application une méthode qui libère le mutex et le ferme.

2

Tout d'abord ... pourquoi avez-vous besoin de redémarrer une application tous les jours?

Je pense qu'il existe une meilleure solution qu'une application qui redémarre à 2 heures du matin tous les jours. Par exemple, vous pouvez avoir une fuite de mémoire ... comme décrit dans votre commentaire. S'attaquer à cela pourrait être un meilleur endroit pour concentrer vos efforts. Redémarrer une application pré-périodique pour éviter une fuite de mémoire serait considéré par la plupart des programmeurs, y compris moi-même, comme un hack.

+1

Qu'est-ce que cela a à voir avec la question? Le fait est que je voudrais recommencer tous les jours à 2h du matin. – Brad

+0

Le pourquoi est important ... et j'ai l'impression que c'est la première chose que la plupart des gens vont se demander. –

+2

@Brad - le pourquoi est important parce que (comme avec d'autres questions ici sur SO) parfois le problème sous-jacent peut être résolu rendant votre problème de surface discutable. La question est tout à fait légitime, bien que je l'aurais probablement posté dans les commentaires au lieu d'une réponse réelle. – AllenG

2

J'ai rencontré ce problème par le passé, et je crois que le problème était que le mutex de l'instance en cours d'exécution n'était pas libéré avant que le mutex de la seconde instance ne le vérifie. Pour résoudre cela, ce que j'ai fait a été fourni un moyen de transmettre le contrôle à mon formulaire principal avec une indication de redémarrer; de sorte que la partie Shutdown du Restart n'ait pas à effectuer de tâches sauf pour quitter.

3

Par hasard, utilisez-vous plusieurs threads? Si vous n'arrêtez pas vos threads d'arrière-plan, ils continueront à exécuter votre processus, même via un appel à Application.Restart.

J'ai collé dans un code ci-dessous qui illustre ce comportement. Pour le voir, compilez un projet de test avec le code ci-dessous et exécutez-le. (vous devrez mettre un bouton sur le formulaire et affecter le gestionnaire de clic que j'ai défini dans le code ci-dessous). Démarrez le Gestionnaire des tâches, accédez à l'onglet Processus et assurez-vous d'ajouter la colonne PID (ID du processus) à la vue.

Chaque fois que vous cliquez sur le bouton, l'application redémarre, mais vous devriez voir l'ancien processus toujours bloqué en mémoire (en raison d'un thread d'arrière-plan qui n'a pas été fermé).

 

    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      // start a background thread that will never be exited. 
      System.Threading.Thread thread = new System.Threading.Thread(delegate() { while (true) System.Threading.Thread.Sleep(1000); }); 
      thread.Start(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      Application.Restart(); 
     } 
} 
 

En supposant que cela est votre problème, la meilleure façon de le corriger est de mettre une sorte de contrôle dans vos fils de fond (même un drapeau bool fera). Demandez-leur de vérifier périodiquement et quittez normalement lorsque votre application s'arrête. Remarque: vous pouvez définir la propriété d'arrière-plan du thread sur true et la quitter automatiquement, mais si vous le faites, vous n'avez aucun contrôle sur l'instruction exécutée par le thread à sa sortie. t effectuer tout type de nettoyage. Il est préférable de coder votre propre chèque.

Questions connexes