Friday 22 September 2017

Waitforexit Hasexited


Il codice assomiglia quasi questo: Come si può vedere, il codice avvia un processo cmd. exe e passa ad essa il comando che voglio da eseguire. Rioriento StandardError e StandarOutput per leggerli dal codice. Il codice li legge prima del processo. WaitForExit (Timeout) chiamata come raccomandato da Microsoft (ne parleremo più avanti). Il problema sorge se il comando mando a cmd. exe non termina o si blocca a tempo indeterminato. Nel codice che ho usato il comando ping - t 8.8.8.8 che, a causa del l'opzione - t, ping l'ospite senza fermarsi. Cosa succede Il processo cmd. exe insieme con il comando - t ping mai uscite e non chiude mai il flusso stdout e così il nostro codice si blocca al () Linea process. StandardOutput. ReadToEnd uscita perché cant riescono a leggere tutto il flusso. Lo stesso accade anche se un comando in un file batch si blocca per qualsiasi motivo e in modo che il codice di cui sopra potrebbe funzionare continuamente per anni e poi appendere improvvisamente senza alcun motivo apparente. Prima ho scritto che la sua consiglia di leggere i flussi reindirizzate prima del processo. WaitForExit (Timeout) chiamata, e questo è particolarmente vero se si utilizza la firma WaitForExit senza il timeout. Se si chiama processo. WaitForExit () prima di leggere i flussi reindirizzati: codice 2: si può sperimentare un deadlock se il comando si collega alla cmd. exe o il processo che si sta chiamando riempie l'output standard o standard error. Questo perché il nostro codice sopraelevazione raggiungere le linee di processo di uscita. StandardOutput. ReadToEnd () È un dato di fatto del processo figlio (il comando ping o un file batch o un processo che si sta eseguendo qualsiasi altra cosa) potete andare sul se il nostro programma di doesnt leggere i buffer piene dei corsi d'acqua e questo cant accadere perché il codice è appesa a la linea con processo. WaitForExit (), che aspettare per sempre per il progetto figlio per uscire. La dimensione predefinita di entrambi i flussi è di 4096 byte. È possibile verificare questo due dimensioni con questi file batch: Il primo script scrive 4096 byte standard output e il secondo di errore standard. Salvare uno di questi in C: testbuffsize. bat ed eseguire il nostro processo di programma chiamante. WaitForExit () prima del processo di uscita. StandardOutput. ReadToEnd (), come nel codice 2. è possibile farlo scrivendo CommandResult Risultato ExecuteShellCommandSync (c: testbuffsize. bat, 1000) alla riga 13 del codice 1. Il codice solito appendere ma se si scrive un altro byte in uno qualsiasi dei due corsi d'acqua che sarà traboccare la dimensione del buffer rendendo il programma appendere. Se avete bisogno di reindirizzare e leggere l'errore di uscita o standar di serie la soluzione migliore è quella di leggere in modo asincrono. Un ottimo modo per fare questo è proposto da Mark Byers in questa discussione StackOverflow come l'ultima cosa si prega di notare che se il processo figlio esce solo perché si utilizza il processo. WaitForExit (Timeout) firma e va effettivamente in timeout si dovrebbe uccidere il processo di cmd. exe e le sue possibili children. I hanno osservato che Process. HasExited a volte restituisce true anche se il processo è ancora in esecuzione. Il mio codice qui sotto inizia un processo con il nome testprogram. exe e quindi attende che per uscire. Il problema è che a volte ho gettato l'eccezione sembra che anche se HasExited restituisce true il processo in sé è ancora vivo nel sistema - come può essere il mio programma scrive un file di log appena prima che termina e quindi ho bisogno di essere assolutamente assicurarsi che esista questo file di registro (aka il processo è terminatedfinished) prima di leggerlo. Controllo continuo per la sua esistenza non è un'opzione. UPDATE: Ho appena provato in attesa con process. WaitForExit () al posto del ciclo di controllo e il risultato è esattamente lo stesso. Aggiunta: Il codice di cui sopra è stato solo per dimostrare un problema più chiara allo stesso modo. Per far capire il mio problema non è che posso ancora ottenere una sospensione del processo con Process. GetProcessesByName (testprogram) dopo aver impostato HasExited a true. Il vero problema è che il programma sto facendo funzionare esternamente scrive un file - solo prima - termina (con garbo). Io uso HasExited di verificare quando il processo è terminato e quindi so di poter leggere il file (perché il processo è terminato), ma sembra che HasExited restituisce true volte anche quando il programma non ha ancora scritto il file su disco. Ecco il codice di esempio che illustra il problema esatto: ha chiesto 25 marzo 10 al 21:52 johnrl I39m chiedendo se tutto va come si pensa si trovino. Non ho mai avuto problemi con la gestione dei processi di questo tipo. Forse avvia un processo figlio ed esce dalla principale, o le modifiche PID, per qualche motivo, o pratiche di dumping è fatto in un altro processo, come funziona in finestre segnalazione degli errori o. there39s semplicemente troppe variabili. È possibile utilizzare ProcMon (Sysinternals) per ottenere ulteriori informazioni su quale processo fa cosa e verificare se pid39s in Process Explorer (Procexp da Sysinternals) si prega di ndash atlaste 18 Gennaio 13 ad 7:20 11 risposte Mi rendo conto che questo è un vecchio post, ma in mia ricerca per scoprire perché la mia app in esecuzione l'evento Exited prima l'applicazione aveva anche aperto ho scoperto una cosa che ho anche se potrebbe essere utile alle persone si verifica questo problema in futuro. Quando viene avviato un processo, viene assegnato un PID. Se l'utente è quindi richiesto con la finestra di dialogo Controllo account utente e seleziona Sì, il processo viene riavviato e assegnato un nuovo PID. Mi sono seduto con questo per un paio d'ore, speriamo che questo può risparmiare tempo qualcuno. risposto 22 Ottobre 14 at 13:11 Io vi suggerisco di provare in questo modo: ogni caso. nella pagina di MSDN di HasExited Im leggere la seguente nota hightlighted: Quando l'uscita standard è stato reindirizzato a gestori di eventi asincroni, è possibile che l'elaborazione di uscita non avrà completato quando questa proprietà restituisce true. Per garantire che la gestione degli eventi asincrona è stata completata, chiamare il sovraccarico WaitForExit () che accetta nessun parametro prima di controllare HasExited. Questo potrebbe essere in qualche modo collegato al tuo problema, come si reindirizza tutto. risposto 15 Gennaio 13 ad 15:52 Lo so, questo è un vecchio post, ma mi può aiutare qualcuno. Le bugie di classe processo a volte HasExited torneranno vero se il processo è terminato o se il processo viene eseguito con privilegi di amministratore e il programma ha solo privilegi utente. risponde 4 15 gennaio alle 20:56 Quindi, solo per un ulteriore indagine sulla causa principale del problema si dovrebbe forse controllare che cosa è realmente accadendo utilizzando Process Monitor. Basta avviarlo e includere il programma esterno e il proprio strumento e lasciarlo registrare ciò che accade. All'interno del registro si dovrebbe vedere come strumento esterno scrive nel file di output e come si apre il file. Ma all'interno di questo registro si dovrebbe vedere in quale ordine tutti questi accessi avvengono. La prima cosa che mi è venuta in mente è che il doesnt menzogna classe Process e il processo è davvero andato quando si dice così. Quindi problema è che a questo punto nel tempo, sembra che il file non è ancora completamente disponibile. Credo che questo sia un problema del sistema operativo. causa che detiene alcune parti del file ancora all'interno di una cache che non è completamente scritto sul disco e lo strumento si è semplicemente uscito senza risciacquo suoi handle di file. Con questo in mente si dovrebbe vedere all'interno del registro che lo strumento esterno ha creato il file, è uscito e dopo che sarà flushedclosed il file (da parte del sistema operativo forse rimuovere eventuali filtri quando hai trovato questo punto all'interno del registro). Quindi, se le mie supposizioni sono corrette la causa principale sarebbe il cattivo comportamento del vostro strumento esterno che non potete modificare in tal modo portando ad aspettare semplicemente un po 'dopo che il processo è terminato e la speranza che il timeout è abbastanza a lungo per ottenere il file flushedclosed dal OS (magari cercare di aprire il file in un ciclo con un timeout fino a che non è riuscita). risposto 16 Gennaio 13 ad 00:36 Prima di tutto, sei sicuro testprogram non depongono le uova un processo a sé stante e uscire senza aspettare quel processo per terminare. A che fare con un certo tipo di condizione gara qui, e testprogram può essere significativo. Secondo Id punto, come fare è su questo - ho bisogno di essere assolutamente sicuri che esista questo file di log. Beh, non vi è nulla di simile. È possibile effettuare la verifica, e quindi il file è andato. Il modo più comune per affrontare questo non è quello di controllare, ma piuttosto di fare ciò che si vuole fare con il file. Vai avanti, leggere, intercettare le eccezioni, riprovare se la cosa sembra instabile e non avete intenzione di cambiare nulla. Il check-e-do funzionale non funziona bene se si dispone di più di un attore (filo o altro) nel sistema. Un sacco di idee casuali segue. Hai provato a usare FileSystemWatcher e non a seconda del completamento della procedura Fa niente di meglio se si tenta di leggere il file (non controllare se esiste, ma agendo invece) in caso process. Exited Non dovrebbe è il sistema Anything sano sospetto in caso log può qualche politica antivirus davvero aggressiva essere coinvolto (Cant dice molto senza vedere tutto il codice e guardando in testprogram.) risponde 17 Gennaio 13 ad 21:46 Per cominciare, c'è un problema con l'utilizzo Process. WaitForExit invece di polling comunque , è tecnicamente possibile per il processo per uscire da un punto di vista utilizzabile ma il processo ancora in giro per breve tempo, mentre lo fa cose del genere cache del disco a filo. È il file di registro particolarmente grandi (o qualsiasi operazione che sta eseguendo pesante sulla scrittura su disco) ha risposto 25 Mar 10 in 21:56 La dimensione massima assoluta file di log è di circa 1 MB. La ragione per cui io uso polling è che ho bisogno di essere in grado di interrompere il compito di attesa in qualsiasi momento e con WaitForExit sto bloccato almeno fino timeout. Secondo te è infatti possibile che il programma potrebbe essere vampate di calore it39s flussi su disco, anche se HasExited ritorna vero ho trovato strano che il processo non è completamente deadgone nella lista dei processi in cui HasExited è vero. Si doesn39t menzionare eventuali circostanze particolari nella documentazione, per quanto posso dire. ndash johnrl 25 10 Mar alle 22:03 E 'qualcosa che ho visto prima, ma non per le dimensioni che le piccole. Come sottolineato da un altro commentatore se la classe Process sarà mantenere un riferimento al processo, si potrebbe desiderare di chiamare Dispose sulla istanza di processo dopo aver controllato per l'uscita, ma prima si cerca di trovare nella lista dei processi. ndash Tiranide 26 marzo 10 al 03:35 Ho solo una singola istanza in esecuzione e io ho cercato di mantenere il Task Manager di Windows aperta e guardare la lista dei processi (anche controllando i ID39s, corrispondono), e in effetti quando il mio codice genera l'eccezione il processo è ancora nell'elenco. A volte si chiude quasi istantaneamente quando viene generata l'eccezione, altre volte si può prendere un secondo o due a scomparire. I39m non è sicuro se Task Manager può essere attendibile (ritardo forse), ma il fatto è che il mio codice genera l'eccezione - non ogni volta, ma in tutto 110 ° delle piste lo fa. ndash johnrl 25 marzo 10 alle 22:10 Una volta process. HasExited è vero, allora il processo è terminato. It39s morti. Può essere uno zombie per un certo periodo di tempo, soprattutto se ci sono handle aperti per l'oggetto processo. Il fatto che GetProcessByName () potrebbe a volte tornare quel processo non significa altro che il processo è ancora uno zombie. Si dovrebbe process. Dispose () per assicurarsi che che la maniglia viene rilasciata. Ma il vostro quottestquot utilizzando GetProcessByName non è semplicemente una cosa ragionevole da fare. process. HasExited è l'unico test affidabile si può fare, e che già ha fatto. ndash John Knoeller 26 marzo 10 alle 9:01 sembra ragionevole. Ma io don39t capisco come mai che il file 39testprogram39 scrive (che è fa proprio prima che si chiuda), isn39t scritti su disco quando HasExited è vero. Come è possibile se il processo è uno zombie (allora dovrebbe avere tutto scaricati su disco, a destra). Smaltimento l'oggetto processo ha alcun effetto sul programma gestito dal processo per quanto ne so così come sarebbe questo aiuto ndash johnrl 26 marzo 10 alle 13:05 Se una maniglia è aperto il processo, il sistema operativo rilascia la memoria del processo quando il processo è terminato, ma mantiene informazioni amministrative sul processo, come la maniglia, codice di uscita, e tempo di uscita. Probabilmente non legato, ma la sua pena di notare. Se la sua solo un problema 110 del tempo, e il processo scompare dopo ogni caso di un secondo, a seconda del vostro uso del HasExited, provare solo l'aggiunta di un altro ritardo dopo i lavori di controllo HasExited, come e vedere se il problema persiste. Personalmente, Ive ha sempre e solo usato il gestore Exited eventi invece di qualsiasi tipo di sondaggi, e un involucro personalizzato semplicistico intorno System. Diagnostics. Process di gestire le cose come la sicurezza filo, avvolgendo una chiamata a CloseMainWindow () seguito da WaitForExit (timeout) e, infine, Uccidere(). la registrazione, eccetera, e mai riscontrato un problema. risposto 25 marzo 10 al 22:34 Forse il problema è nella testprogram Fa questo codice ben flushclose ecc Mi sembra se testprogram scrive un file su disco, il file dovrebbe almeno essere disponibile (vuota o non) risposto 29 Apr 10 a 08:27 Se si dispone di un'applicazione web, e la vostra programprocess esterna sta generando file (scrittura su disco) controllare se i tuoi IIS hanno diritti di scrittura a quella cartella, se non sulle proprietà di sicurezza aggiungere l'autorizzazione per l'utente di IIS, che è stata la ragione il mio caso, stavo ricevendo process. HasExited vero, ma ha prodotto i file dal processo non è stato completato, dopo aver lottato per un po 'aggiungo autorizzazioni complete alla cartella in cui processo si contorceva e process. Refresh (), come descritto Zarathos dall'alto e tutto stava lavorando come previsto. risposto 18 Apr 14 at 00:16 Usa processname. Refresh () prima di verificare se processo è terminato o no. Refresh () cancellerà tutte le informazioni memorizzate nella cache relative al processo. risposto 30 Apr 15 alla 07:44 vedo questo è stato downvoted - eventuali approfondimenti sul perché I39m avere un problema simile a OP e sto solo cercando di ordinare attraverso tutte queste risposte. ndash Kevin Holt 22 novembre 16 alle 18:28 La vostra risposta 2017 Stack Exchange, Inc

No comments:

Post a Comment