2008-12-09 17 views
2

J'appelle un exécutable en C#. Lorsque l'exécutable s'exécute, il écrit sur la console afin que le code C# obtienne la sortie de la console et l'écrit dans un fichier texte. Lorsque l'accident se produit, deux ou trois choses se produisent.Appeler un exécutable en utilisant le processus se bloque par intermittence

1) La sortie du fichier texte n'est pas complètement écrite. 2) Le processus exécutable semble fonctionner complètement car il génère un rapport comme une exécution réussie.

Je soupçonne que la raison de cet accident est en raison de la façon dont j'écris le fichier.

Mise à jour: - En ce qui concerne le crash, une boîte de dialogue s'affiche disant que le "Gestionnaire a rencontré un problème et doit fermer." Nous sommes désolés pour le désagrément. " Ensuite, il a un bouton OK. Lorsque vous cliquez sur OK, une boîte de dialogue que j'ai paramétrée vous demande si je veux redémarrer le gestionnaire.

  • L'application de gestionnaire qui appelle l'exécutable est à un seul thread. L'exécutable peut être multithread.

Voici un petit extrait de l'appel:

// Set up process to redirect standard output and standard error to 
    // a file. 
    process.StartInfo.UseShellExecute = false; 
    process.StartInfo.RedirectStandardOutput = true; 
    process.StartInfo.RedirectStandardError = true; 
    FileInfo ofi = new FileInfo(outputPath); 
    FileStream ofs = ofi.OpenWrite(); 
    StreamWriter sw = new StreamWriter(ofs); 
    WriteToTextWriterEventHandler wtsweh = new WriteToTextWriterEventHandler(sw); 
    DataReceivedEventHandler handler = wtsweh.HandleDataReceived; 
    process.OutputDataReceived += handler; 
    process.ErrorDataReceived += handler; 
    // 

    statusAcceptor.ReportStatus("Running process."); 
    process.Start(); 
    process.BeginOutputReadLine(); 
    process.BeginErrorReadLine(); 

    statusAcceptor.ReportStatus("Waiting for process to complete."); 
    process.WaitForExit(); 
    int processExitCode = process.ExitCode; 
    process.Close(); 
    sw.Close(); 


    // 
    private class WriteToTextWriterEventHandler 
    { 
     private TextWriter tw; 

     public WriteToTextWriterEventHandler(TextWriter tw) 
     { 
      this.tw = tw; 
     } 

     public void HandleDataReceived(object sendingProcess, 
     DataReceivedEventArgs outLine) 
     { 
      // Collect the sort command output. 
      if (!String.IsNullOrEmpty(outLine.Data)) 
      { 
       tw.Write(Environment.NewLine + outLine.Data); 
      } 
     } 
    } 
+0

étiquette de filetage, mais aucune mention de filetage? – leppie

+0

Pourriez-vous être plus précis concernant l'accident s'il vous plaît? (et je suis d'accord avec lepie sur la balise de filetage) –

Répondre

1

Essayez d'ajouter un vidage après le tw.Write. Cela devrait provoquer la production complète jusqu'à l'échec de la production, qui peut inclure des messages d'erreur de l'exécutable (si c'est ce qui plante)? ​​

+0

J'ai ajouté une couleur après l'écriture et jusqu'à présent, je n'ai pas été en mesure de reproduire le crash pendant quelques jours maintenant. Pourquoi ajouter la chasse d'eau? – arc1880

+0

Autant que je voudrais prendre le crédit pour cela ... Je n'en ai aucune idée.Ma pensée derrière la chasse d'eau était simplement que le flux de sortie entier pourrait ne pas être affiché, masquant potentiellement un message d'erreur utile. – GWLlosa

1

Quel est l'accident que vous obtenez? Une exception .Net?

Si le fichier n'est pas écrit complètement, cela peut être dû au fait que vous ne videz pas le flux dans le fichier, puis le fermez.

Je pense qu'il peut être un problème que vous utilisez le même flux pour les messages de sortie standard et de sortie d'erreur. Cela peut entraîner des problèmes de concurrence.

0

J'ai testé votre code avec un certain nombre d'exécutables différents et était incapable de le faire s'écraser comme vous le décrivez. Peut-être que c'est un problème avec le processus que vous exécutez?

1

Il est probablement dans vos gestionnaires. Vous devez mettre en logique pour gérer les exceptions levées par les gestionnaires de flux et vous devez mettre en place un mécanisme pour vous assurer que les gestionnaires de flux sont correctement fermés avant d'appeler sur le processus. Des problèmes comme celui-ci sont difficiles à cerner à cause des problèmes de synchronisation avec les gestionnaires d'événements et le processus.close donc ça ne me surprend pas les autres affiches n'ont pas été capables de le reproduire. Mais je l'ai vu en action. Le problème est que EventHandler est actif jusqu'à ce qu'il soit fermé en appelant cancelErrorRead ou cancelOutputRead ou le processus se termine. Eh bien, s'il est encore occupé à vider une sortie à la toute fin du processus, alors que le thread principal se rend à Process.Fermer ... BOOM

Questions connexes