Sunday 12 March 2017

Waitforexit Hang Seng

Le code ressemble presque à ceci: Comme vous pouvez le voir, le code démarre un processus cmd. exe et lui passe la commande que je veux être exécutée. Je redirige StandardError et StandarOutput afin de les lire à partir du code. Le code les lit avant le processus. WaitForExit (Timeout) appel comme recommandé par Microsoft (plus sur cela plus tard). Le problème se produit si la commande que j'envoie à cmd. exe ne se termine jamais ou ne se bloque pas indéfiniment. Dans le code j'ai utilisé la commande ping t 8.8.8.8 qui, à cause de l'option t, pings l'hôte sans s'arrêter. Ce qui se passe Le processus cmd. exe avec la commande ping t ne quitte jamais et ne ferme jamais le flux stdout et donc notre code se bloque à la ligne Output. StandardOutput. ReadToEnd () car il ne peut pas réussir à lire tout le flux. La même chose se produit également si une commande dans un fichier de commandes se bloque pour une raison quelconque et que le code ci dessus peut fonctionner continuellement pendant des années et puis se bloquer soudainement sans raison apparente. Avant que j'ai écrit que son recommandé de lire les flux redirigés avant le processus. WaitForExit (Timeout) appel, bien cela est particulièrement vrai si vous utilisez la signature WaitForExit sans le délai d'attente. Si vous appelez processus. WaitForExit () avant de lire les flux redirigés: code 2: vous pouvez rencontrer un blocage si la commande que vous attachez à cmd. exe ou le processus que vous appelez remplit la sortie standard ou l'erreur standard. Ceci parce que notre code ne peut atteindre le processus de sortie lignes. StandardOutput. ReadToEnd () En fait, le processus enfant (la commande ping ou un fichier batch ou tout autre processus que vous exécutez) ne peut pas continuer si notre programme ne lit pas les tampons remplis des flux et cela ne peut pas arriver car le code est suspendu à La ligne avec le processus. WaitForExit () qui attendra pour toujours le projet enfant pour quitter. La taille par défaut des deux flux est 4096 octets. Vous pouvez tester ces deux tailles avec ces fichiers batch: Le premier script écrit 4096 octets à la sortie standard et le second à l'erreur standard. Enregistrez l'un de ces dans C: testbuffsize. bat et exécutez notre processus d'appel de programme. WaitForExit () avant le processus de sortie. StandardOutput. ReadToEnd () comme dans le code 2. Vous pouvez le faire en écrivant CommandResult Résultat ExecuteShellCommandSync (c: testbuffsize. bat, 1000) à la ligne 13 du code 1. Le code ne sera pas accrocher, mais si vous écrivez un octet de plus dans l'un des deux flux, il va déborder la taille du tampon de faire le programme pendre. Si vous avez besoin de rediriger et de lire la sortie standard ou l'erreur standar, la meilleure solution est de les lire de manière asynchrone. Un excellent moyen de le faire est proposé par Mark Byers dans ce thread stackoverflow Comme la dernière chose s'il vous plaît noter que si le processus enfant se ferme uniquement parce que vous utilisez le processus. WaitForExit (Timeout) signature et il est effectivement en timeout, vous devriez tuer le processus cmd. exe et ses enfants possibles. Elina: merci pour votre réponse. Certaines notes au bas de cette doc MSDN (msdn. microsoften uslibraryhellip) avertissent des potentiels blocages si vous lisez à la fin des flux stdout et stderr redirigés synchroniquement. Il est difficile de dire si votre solution est susceptible à ce problème. En outre, il semble que vous envoyez le process39 stdoutstderr sortie en arrière en entrée. Pourquoi. ) Ndash Matthew Piatt Sep 26 16 at 4:42 Il s'agit d'une solution plus moderne, attendue, Task Parallel Library (TPL) pour 4.5 et plus. Exemple d'utilisation Exécution répondu Oct 5 16 at 10:54 I chose que c'est simple et mieux approche (nous n'avons pas besoin AutoResetEvent): Répondue 14 juin à 14h29 Vrai, mais shouldn39t vous faites. File Name Chemin quotggsci. exequot quot lt Obeycommand. txtquot pour simplifier votre code trop Ou peut être quelque chose d'équivalent à quotecho quotggsci. exequot quotggsci. exequot commande si vous ne don39t vraiment envie d'utiliser un fichier obeycommand. txt distinct. Ndash Amit Naidu Jun 4 13 at 22:03 Votre solution n'a pas besoin AutoResetEvent mais vous sondage. Lorsque vous faites des sondages au lieu d'utiliser l'événement (quand ils sont disponibles) alors vous utilisez l'UC sans raison et qui indiquent que vous êtes un mauvais programmeur. Votre solution est vraiment mauvaise par rapport à l'autre utilisant AutoResetEvent. (Mais je ne vous ai pas donné 1 parce que vous avez essayé d'aider). Ndash Eric Ouellet Nov 7 14 at 18:38 J'avais le même problème, mais la raison était différente. Cela se produira toutefois sous Windows 8, mais pas sous Windows 7. La ligne suivante semble avoir causé le problème. La solution était de ne pas désactiver UseShellExecute. J'ai maintenant reçu une fenêtre popup Shell, qui est indésirable, mais beaucoup mieux que le programme d'attente pour rien de particulier à se produire. Donc, j'ai ajouté le travail suivant autour de cela: Maintenant, la seule chose qui me dérange est de savoir pourquoi cela se passe sous Windows 8 en premier lieu. J'ai essayé de faire une classe qui permettrait de résoudre votre problème en utilisant asynchrone flux lire, en prenant en compte Mark Byers, Rob, stevejay réponses. Ce faisant, j'ai réalisé qu'il y avait un bug lié au flux de sortie de processus asynchrone. Vous ne pouvez pas faire cela: Vous recevrez System. InvalidOperationException. StandardOut n'a pas été redirigé ou le processus n'a pas encore démarré. Ensuite, vous devez démarrer une sortie asynchrone lue après le démarrage du processus: En faisant cela, faites une condition de course car le flux de sortie peut recevoir des données avant de le définir en asynchrone: alors certaines personnes pourraient dire que vous avez juste à lire le flux avant vous Définissez le en mode asynchrone. Mais le même problème se produit. Il y aura une condition de course entre la lecture synchrone et configurera le flux en mode asynchrone. Il n'existe aucun moyen de réaliser une lecture asynchrone sécurisée d'un flux de sortie d'un processus de la manière réelle Process et ProcessStartInfo a été conçu. Vous êtes probablement mieux en utilisant la lecture asynchrone comme suggéré par d'autres utilisateurs pour votre cas. Mais vous devez être conscient que vous pourriez manquer certaines informations en raison de la condition de course.


No comments:

Post a Comment