2016-11-18 1 views
-1

Je rencontre une chose étrange et je n'arrive pas à trouver la raison pour laquelle cela se produit.Démarrer le processus depuis Service hung UseShellExecute false

J'ai un service.exe où je recueille des données à partir du registre de configuration, puis je démarre n processus.

Exemple de code:

_mProcess.StartInfo = new ProcessStartInfo 
{ 
    FileName = Command, 
    Arguments = Argument, 
    WorkingDirectory = WorkDir 
}; 
_mProcess.Start(); 
Pid = _mProcess.Id; 

Mon Pid contient l'identifiant du processus.

Maintenant, j'ai ajouté UseShellExecute = false pour obtenir le StandardOutput.

Nouveau code exemple:

_mProcess.StartInfo = new ProcessStartInfo 
{ 
    FileName = Command, 
    Arguments = Argument, 
    WorkingDirectory = WorkDir //, 
    //CreateNoWindow = true, 
    UseShellExecute = false, 
    //RedirectStandardOutput = true, 
    RedirectStandardError = true 
    //RedirectStandardInput = true 
}; 
_mProcess.Start(); 
Pid = _mProcess.Id; 

using (var reader = _mProcess.StandardError) 
{ 
    _logger.ToLog("", Company, reader.ReadToEnd(), "RCluster.log", "service"); 
} 

Dans ce cas, le processus de retour de nouveau une erreur que je peux stocker à mon fichier journal. Problème: Ce code fait partie d'une méthode pour démarrer un processus que j'appelle plusieurs fois (en fonction de ma configuration). Donc, avec ce code, le premier processus est appelé, les processus suivants ne le sont pas. D'une certaine manière, le service attend le premier service maintenant. Je pensais que cela se produit uniquement avec WaitForExit.

Alors, comment puis-je obtenir une sortie d'erreur standard, mais ne pas faire du bloc de processus ma tâche principale pour continuer?

+0

Votre processus attend que le lecteur d'erreur trouve la fin du flux et bloque jusqu'à ce que le processus soit terminé. Lancez le traitement des erreurs dans une autre tâche thread ou asynchrone. – Gusman

Répondre

0

@Gusman: Ajoutez votre commentaire comme réponse, vous m'avez apporté à la bonne réponse. Ensuite, je peux accepter votre commentaire comme réponse.

À l'abaisseur: Explication pourquoi serait apprécié.

Pour tous: J'ai ajouté du code pour démarrer le nouveau processus en tant que thread. Dans ce cas, il est logique de le démarrer dans un autre thread pour récupérer les messages `StandardError, mais ne bloquez pas le processus principal (qui est un service dans mon cas qui démarre de nombreux sous-processus).

 // start as new thread to prevent blocking 
     var ths = new ThreadStart(() => 
     { 
     mProcess.Start(); 
     Pid = mProcess.Id; 

     // write pid file 
     File.WriteAllText(RubyDir + @"\tmp\pids\" + Port + @".pid", Pid.ToString()); 

     using (var reader = mProcess.StandardError) 
     { 
      var errorMsg = reader.ReadToEnd(); 
      if (errorMsg.Length > 0) _logger.ToLog("", Company, errorMsg, "SOLR.log", "service"); 
     } 
     }); 
     var th = new Thread(ths); 
     th.Start();