J'utilise Process. Start pour démarrer un fichier de commandes. Le fichier de commandes utilise la commande START pour lancer plusieurs programmes en parallèle, puis quitte. Une fois le fichier batch terminé, Process. HasExited devient vrai et Process. ExitCode contient le code de sortie correct. Mais quand j'appelle Process. WaitForExit () il se bloque jamais renvoie. Le code suivant illustre le problème. Il crée un fichier batch, le démarre et imprime: Il doit alors imprimer: mais il ne le fait jamais (même si HasExited est vrai et que nous avons déjà un ExitCode). J'ai remarqué que cela ne se produit que lorsque le fichier de commandes contient des commandes START et que la sortie standard ou l'erreur standard sont redirigées. Pourquoi WaitForExit () ne retourne t il pas Quelle est la bonne façon d'attendre un tel processus pour quitter Est il sécuritaire de simplement sondage Process. HasExited ou cela peut entraîner d'autres problèmes PS. Je viens de remarquer que l'appel WaitForExit (100000) avec un délai d'expiration énorme (qui ne vient pas expirer) revient immédiatement lorsque le processus se termine. Wierd. Sans délai, il se bloque. Il existe une différence fondamentale lorsque vous appelez WaitForExit () sans un time out, il garantit que le stdouterer redirigé ont renvoyé EOF. Cela vous assure que vous avez lu toute la sortie qui a été produite par le processus. Nous ne pouvons pas voir ce que quotonOutputquot fait, mais les cotes élevées qu'il deadlocks votre programme parce qu'il fait quelque chose de méchant comme supposer que votre thread principal est inactif quand il est effectivement coincé dans WaitForExit (). Ndash Hans Passant Nov 3 14 at 12:06 Cela semble être un artefact (Id dire bogue) dans la mise en œuvre spécifique de la gestion asynchrone par événement de StandardOutput et StandardError. J'ai remarqué que pendant que je pouvais facilement reproduire votre problème, simplement en exécutant le code que vous avez fourni (exemple de code excellent, par la façon dont.)), Le processus n'a pas réellement bloquer indéfiniment. Il est plutôt retourné de WaitForExit () une fois que les deux processus enfant qui avaient été démarrés avaient eux mêmes quitté. Cela semble être une partie intentionnelle de la mise en œuvre de la classe Process. En particulier, dans la méthode Process. WaitForExit (), une fois qu'il a terminé d'attendre sur la poignée de processus lui même, il vérifie si un lecteur pour stdout ou stderr a été créé si oui, et si la valeur de délai d'attente pour WaitForExit ) Est infinie (c'est à dire 1), le code attend la fin de flux sur le (s) lecteur (s). Chaque lecteur respectif est créé uniquement lorsque la méthode BeginOutputReadLine () ou BeginErrorReadLine () est appelée. Les flux stdout et stderr ne sont eux mêmes pas fermés tant que les processus enfant n'ont pas été fermés. Donc, attendre sur la fin de ces flux va bloquer jusqu'à ce que cela arrive. Que WaitForExit () devrait se comporter différemment selon si on a appelé l'une des méthodes qui commencent la lecture événementielle des flux ou pas, et surtout étant donné que la lecture de ces flux directement ne cause pas WaitForExit () se comporter de cette façon, crée Une incohérence dans l'API qui le rend beaucoup plus difficile à comprendre et à utiliser. Alors que Id personnellement appeler cela un bogue, je suppose que son possible que les implémenteurs de la classe Process sont conscients de cette incohérence et créé à dessein. Dans tous les cas, le contournement serait de lire StandardOutput et StandardError directement au lieu d'utiliser la partie événementielle de l'API. (Bien que, bien sûr, si les codes devaient attendre sur ces flux, on verrait le même comportement de blocage jusqu'à ce que l'enfant processus fermer.) Par exemple (C, car je ne sais pas F assez bien pour gifler un exemple de code comme ça ensemble rapidement :)): J'espère que le travail ci dessus ou quelque chose de semblable abordera la question de base que vous rencontrez. Mes remerciements au commentateur Niels Vorgaard Christensen pour m'avoir dirigé vers les lignes problématiques dans la méthode WaitForExit (), afin que je puisse améliorer cette réponse. À ma connaissance, la méthode Process. WaitForExit (int32) ne signifie pas de quitter le timeout. La surcharge WaitForExit (Int32) est utilisée pour faire attendre le thread actuel jusqu'à ce que le processus associé se termine. Cette surcharge demande au composant Process d'attendre un temps fini pour que le processus quitte. Si le processus associé ne se termine pas à la fin de l'intervalle car la demande de terminaison est refusée, false est renvoyé à la procédure d'appel. Vous pouvez spécifier un nombre négatif (Infini) pendant des millisecondes. Et Processus. WaitForExit (Int32) se comportera de la même façon que la surcharge WaitForExit Si vous souhaitez fermer le processus, vous pouvez utiliser le code suivant pour faire comme vous voulez: Vin Jin MSFT MSDN Communauté Support Feedback pour nous Obtenir ou demander Exemple de code de Microsoft Pour marquer les réponses comme des réponses si elles les aident et les désélectionnent s'ils ne fournissent aucune aide. Lundi 20 juin 2011 6:26 AM Oui, mais ce n'est pas Process. WaitForExit (Int32) qui ne fonctionne pas. Cette fonction fonctionne très bien avec beaucoup d'exécutables. Le problème est que cette fonction ne fonctionne pas avec PsExec et une redirection de sortie standard. Son travail seulement sans utiliser la redirection ou sans utiliser un timeout. Lundi 20 juin 2011 06:41 Je ne sais pas pourquoi vous voulez utiliser keywork et pourquoi voulez vous redirection seulement lorsque le processus commence Essayez le code suivant: Pour le modifier comme votre demande. Il peut bien fonctionner. Voici le résultat: plus le temps (120000) que vous définissez, plus vous obtenez d'imformation. Donc, je vous suggère d'utiliser la méthode process. WaitForExit () sans paramètres. Merci. Vin Jin MSFT MSDN Communauté Support Feedback pour nous Obtenez ou demandez un échantillon de code de Microsoft N'oubliez pas de marquer les réponses comme des réponses si elles les aident et les désélectionnent s'ils ne fournissent aucune aide. Lundi, juin 20, 2011 9:42 AM Merci pour votre aide. Si j'utilise process. WaitForExit () sans temps, son travail très bien et j'ai la sortie complète. Mais j'utilise psexec pour exécuter un kit de configuration à distance, cette configuration peut geler le processus, donc j'ai besoin d'un timeout et je ne veux pas utiliser l'option d (N'attendez pas que le processus se termine) parce que j'ai les prochaines étapes à exécuter après La mise en place. Monday, June 20, 2011 10:01 AM Que diriez vous de fixer le temps plus longtemps Veuillez le marquer comme réponse, si il aide à résoudre votre problème. Wednesday, June 22, 2011 7:07 AM J'ai essayé avec 300000, son le même comportement. Bien que mon processus d'installation prenne moins de 60000 Le problème n'est pas la durée d'expiration. Le problème est qu'une redirection de sortie standard et une exécution avec un timeout gèlent le processus psexec (seulement psexec, pas un autre.) Wednesday, June 22, 2011 7:19 AM Bonjour, Je sais que c'est un ancien post, mais j'avais Cette même erreur lorsque vous essayez d'exécuter un processus en utilisant le combo WaitFor () 43 RedirectStandardOutput et il se bloquera indéfiniment. J'ai trouvé une solution à mon problème dans un billet de blog de Lucian Wischik, MSFT. Si vous n'avez pas trouvé une solution, ou quelqu'un d'autre à la recherche de ce problème particulier devrait jeter un oeil à cette adresse: Voici une copie de son code grossièrement traduit en C. Mercredi, 30 novembre 2011 22:23 Microsoft effectue un sondage en ligne Pour comprendre votre opinion sur le site Web Msdn. Si vous choisissez de participer, le sondage en ligne vous sera présenté lorsque vous quitterez le site Web Msdn. Voudriez vous participer
Want To Boost Your ClickBank Commissions And Traffic?
ReplyDeleteBannerizer made it easy for you to promote ClickBank products by banners, simply visit Bannerizer, and get the banner codes for your picked ClickBank products or use the Universal ClickBank Banner Rotator to promote all of the ClickBank products.