Waitforexit는 결코 반환하지 않습니다.
App Store를 통해 가져 오기 우리의 응용 프로그램 에서이 게시물을 읽으십시오!
외부 명령 줄 프로세스는 결코 반환되지 않습니다.
다음 명령을 사용하여 외부 명령 줄 응용 프로그램을 실행하고 출력을 다시 읽습니다.
이 코드는 여러 응용 프로그램에서 완벽하게 작동합니다. 지금까지. 문제는 이것입니다 : 나는 지금 "aapt. exe"(안드로이드 APK 응용 프로그램에 대한 정보를 제공하는 도구)를 실행하여 묶음 파일에 사용하고 있으며 코드는 내가 주석 처리 한 지점에서 멈추게됩니다 (반환하지 않음). 총 81 개의 파일 중 3 개의 특정 파일에만 있습니다.
물론 내 첫 번째 생각은 외부 프로그램이 특정 파일에 문제가 있거나 실패했기 때문에 명령 프롬프트에서 수동으로 동일한 명령을 테스트 했으므로 완벽하게 작동합니다! 게다가 : 나는 다음과 같이 코드에 타임 아웃을 추가했다.
그리고이 경우 프로세스가 반환됩니다 (분명히)하지만 재미있는 것은 출력이 정확하고 완벽하다는 것입니다! 이는 외부 프로그램이 끝날 때까지 올바르게 실행되고 있음을 의미하므로 프로세스 자체가 돌아 가지 않는 이유는 무엇입니까 ?? 이것을 디버깅 할 수있는 방법이 있습니까?
편집 : 테스트 시간 후, 나는 결론에 문제가 "RedirectStandardOutput"옵션에있다. 어떤 명령을 실행 / 읽고 어떤 실행에 달려 있더라도 상관 없습니다. 이 적절한 솔루션을 찾지 못했습니다, 나는 stdout 리디렉션을 사용하지 않고 stdout을 파일로 출력 한 다음 프로세스가 종료 될 때 즉시 코드에서 다시 읽는 (끔찍한) 해결 방법을 구현했습니다 (올바르게 종료됩니다). 최소한이 방법). 우아한 해결책은 아니며 여전히이 글의 맨 아래로 가고 싶습니다. 누군가 내 아이디어보다 더 좋은 아이디어를 갖고 있다면 질문을 공개적으로 남겨두고 있습니다.
아마 당신이 proc. WaitForExit () 전에 Dim ret = myOutput. ReadToEnd를 호출 할 필요가 있다고 생각합니다. MSDN은 교착 상태에 대해 WaitForExit ()을 먼저 호출하면 경고합니다. "p. StandardOutput. ReadToEnd 전에 부모 프로세스가 p. WaitForExit를 호출하고 자식 프로세스가 리디렉션 된 스트림을 채우기에 충분한 텍스트를 쓰면 교착 상태가 발생할 수 있습니다. 부모 프로세스는 부모 프로세스가 전체 StandardOutput 스트림에서 읽는 것을 무기한 대기합니다. " 그래서 저는 3/81 파일이 다른 것보다 많은 출력을 가지고 있다고 생각합니다.
끝으로 / C 매개 변수를 추가하려고 시도 했으므로 종료 한 후에 반환됩니다. 예 : cmd / C ""abc. exe ""
여기서 "/ C"는 명령 프롬프트가 완료된 후에 종료하도록 지시하는 것이 중요합니다.
Waitforexit는 결코 반환하지 않습니다.
App Store를 통해 가져 오기 우리의 응용 프로그램 에서이 게시물을 읽으십시오!
Process. WaitForExit는 Process. HasExited가 true 인 경우에도 반환되지 않습니다.
Process. Start를 사용하여 배치 파일을 시작합니다. 배치 파일은 "START"명령을 사용하여 여러 프로그램을 병렬로 시작한 다음 종료합니다.
일단 배치 파일이 완료되면 Process. HasExited가 true가되고 Process. ExitCode에 올바른 종료 코드가 포함됩니다.
하지만 Process. WaitForExit ()을 호출하면 중단되거나 반환되지 않습니다.
다음 코드는 문제를 보여줍니다. 배치 파일을 만들고 시작한 다음 인쇄합니다.
다음을 인쇄해야합니다.
. 하지만 결코하지 않습니다 (HasExited가 true이고 이미 ExitCode가 있음에도 불구하고).
배치 파일에 "START"명령이 들어있을 때와 표준 출력 및 / 또는 표준 오류가 리디렉션 될 때만 발생하는 것으로 나타났습니다.
WaitForExit ()이 반환하지 않는 이유는 무엇입니까?
그러한 프로세스가 종료 될 때까지 기다리는 올바른 방법은 무엇입니까?
Process. HasExited를 폴링하는 것이 안전합니까? 아니면 다른 문제가 발생할 수 있습니까?
추신 : 나는 방금 WaitForExit (100000)을 거대한 시간 초과 (확실히 만료되지 않음)로 호출하면 프로세스가 종료 될 때 즉시 반환하는 것으로 나타났습니다. 위어드. 타임 아웃이 없으면 중단됩니다.
이것은 표준 오류 및 StandardError의 이벤트 기반 비동기 처리의 특정 구현에서 아티팩트 ( "버그"라고 말합니다) 인 것 같습니다.
나는 당신이 제공 한 코드 (훌륭한 코드 예제, 그런데! :)를 실행함으로써 문제를 쉽게 재현 할 수 있었지만, 프로세스는 실제로 무한정 멈추지 않았다는 것을 알았다. 오히려 WaitForExit ()에서 리턴 된 것은 시작된 두 개의 하위 프로세스가 모두 종료 한 후에였습니다.
이것은 Process 클래스 구현의 의도적 인 부분 인 것으로 보인다. 특히 Process. WaitForExit () 메서드에서 프로세스 핸들 자체에 대한 대기가 끝나면 stdout 또는 stderr에 대한 판독기가 만들어 졌는지 확인합니다. 그렇다면 WaitForExit () 호출의 제한 시간 값이 "무한"(즉, -1)이면 코드는 실제로 리더에서 스트림의 끝을 기다립니다.
각각의 독자는 BeginOutputReadLine () 또는 BeginErrorReadLine () 메서드가 호출 될 때만 만들어집니다. stdout 및 stderr 스트림 자체는 자식 프로세스가 닫힐 때까지 닫히지 않습니다. 그래서 그 흐름이 끝날 때까지 그 흐름이 끝날 때까지 기다리게됩니다.
WaitForExit ()은 스트림의 이벤트 기반 읽기를 시작하는 메소드를 호출했는지 여부에 따라 다르게 동작해야하며 특히 해당 스트림을 직접 읽는 것으로 WaitForExit ()이 그런 식으로 동작하지 않으면 API를 이해하고 사용하기가 훨씬 어려워지는 불일치. 나는 이것을 개인적으로 버그라고 부르지 만, Process 클래스의 구현자가이 불일치를 인식하고 그것을 의도적으로 만들었을 가능성이 있다고 생각한다.
어쨌든, 임시 해결책은 API의 이벤트 기반 부분을 사용하는 대신 StandardOutput 및 StandardError를 직접 읽는 것입니다. 물론 코드가 해당 스트림에서 대기하는 경우에도 자식 프로세스가 종료 될 때까지 동일한 차단 동작이 표시됩니다.
예를 들어 (C #은 코드 예제를 이와 같이 빨리 때리기에 충분할만큼 F #을 알지 못하기 때문에) :) :
위의 해결 방법이나 이와 유사한 방법으로 기본 문제를 해결할 수 있기를 바랍니다. Niels Vorgaard Christensen이 WaitForExit () 메서드의 문제가있는 줄로 안내해 주신 데 대해 감사 드려서이 답변을 개선 할 수있었습니다.
월터의 통나무.
. 학습하면서 글쓰기.
2011 년 11 월 18 일 금요일.
Process. WaitForExit (Int32) 문제가 발생합니다.
보시다시피, 코드는 "cmd. exe"프로세스를 시작하고 실행하려는 명령을 전달합니다.
코드에서 ping - t 8.8.8.8 명령을 사용했습니다. - t 옵션으로 인해 호스트를 멈추지 않고 ping합니다. 무슨 일이야? ping - t 명령과 함께 "cmd. exe"프로세스는 절대로 종료되지 않고 stdout 스트림을 닫지 않으므로 코드가 Output = process. StandardOutput. ReadToEnd (); 왜냐하면 모든 스트림을 읽는 데 성공하지 못하기 때문입니다.
배치 파일의 명령이 어떤 이유로 든 중단되고 위의 코드가 계속해서 몇 년 동안 작동 한 다음 명백한 이유없이 갑자기 멈추는 경우에도 마찬가지입니다.
"cmd. exe"에 첨부하는 명령이나 호출중인 프로세스가 표준 출력이나 표준 오류를 채우면 교착 상태가 발생할 수 있습니다. 이것은 코드가 라인에 도달 할 수 없기 때문입니다.
실제로 우리 프로그램이 스트림의 채워진 버퍼를 읽지 않는다면 자식 프로세스 (ping 명령 또는 배치 파일 또는 실행중인 모든 프로세스)를 실행할 수 없습니다. 코드가 프로세스가있는 줄에 매달려 있습니다. WaitForExit () : 자식 프로젝트가 종료 될 때까지 기다립니다.
두 스트림의 기본 크기는 4096 바이트입니다. 다음 배치 파일을 사용하여이 두 가지 크기를 테스트 할 수 있습니다.
Waitforexit는 결코 반환하지 않습니다.
내 응용 프로그램에 다음 코드가 있습니다.
System. Diagnostics. Process proc = new System. Diagnostics. Process ();
다른 응용 프로그램을 통해 이것을 호출하면 프로세스가 중지됩니다.
그런 다음 5 초를 기다렸다가 이제는 정상적으로 작동합니다. 그러나이 시간 초과 값은 시스템 리소스 및 입력 응용 프로그램의 처리량에 따라 달라질 수 있으므로이 문제를 수정하는 더 좋은 방법을 찾아야합니다.
그래서, 내 질문은 우리가 System. Diagnostics를 사용하여 프로세스를 만들고 있다면, OS가 별도의 스레드를 만들고 그것을 기본 스레드 또는 UI 스레드로 만드나요?
또는 System. Threading. Thread와 동일한 CLR 스레드를 만드는 중입니까?
Thread-pool을 사용하여 작업자 스레드를 생성하는 것이 더 좋은 선택일까요?
스레드 풀이 사용자 모드 스케줄링을 사용합니까?
이것에 대한 당신의 도움을 감사하십시오.
System. Diagnostics가 백그라운드 스레드 또는 작업자 스레드도 생성하기 때문에 하루가 끝날 때 변경 사항이 없으므로 별도의 스레드를 다시 만들지 않으므로 그 점을 알아야합니다.
위의 구현과 백그라운드 스레드를 만드는 것의 차이점은 무엇입니까?
응용 프로그램의 내부 및 외부 스레드를 혼란스럽게합니다. UI 스레드에서 WaitForExit을 사용하는 경우. UI 스레드가 응답하지 않게됩니다. 문제가 발생하면 BackgroundWorker의 DoWork 이벤트에 새 프로세스를 생성하십시오. 프로세스가 종료되면 UI 스레드에 경고하는 RunWorkerCompleteEvent가 트리거됩니다.
민 주 (Min Zhu) 마이크로 소프트 우연한 직원의 답변으로 표시 중재자 Monday, July 18, 2011 3:10 AM.
모든 답장.
EnableRaisingEvents = false로 이벤트를 기다리면 WaitForExit을 타이머로 사용하고 있음을 의미합니다. 적절한 값으로 설정하십시오.
EnableRaisingEvents = false로 이벤트를 기다리면 WaitForExit을 타이머로 사용하고 있음을 의미합니다. 적절한 값으로 설정하십시오.
저는 5000을 값으로 주었고 문제를 해결했습니다. 내 걱정은 다른 시스템 자원, 입력 내용 크기 등으로 유사하게 작동합니까?
관련 프로세스가 간격의 끝까지 종료되지 않으면 어떻게됩니까?
Windows는 실시간 운영 체제가 아니므로 모든 타이머는 OS의 일정에 따라 달라집니다. 아마도 System. Timers. Timer가 가장 정확합니다.
& quot; 관련 프로세스가 간격의 끝까지 종료되지 않으면 어떻게됩니까? & quot; 이 기능을 사용 중지했습니다. 이것이 당신이하려는 일이라면, 그것을 가능하게하십시오. 프로세스를 시작하는 데 사용한 스레드를 차단하고 싶지 않으면 백그라운드 스레드에서 시작하십시오. BackgxroundWorker가 이에 적합합니다.
System. Diagnostics가 백그라운드 스레드 또는 작업자 스레드도 생성하기 때문에 하루가 끝날 때 변경 사항이 없으므로 별도의 스레드를 다시 만들지 않으므로 그 점을 알아야합니다.
위의 구현과 백그라운드 스레드를 만드는 것의 차이점은 무엇입니까?
System. Diagnostics가 백그라운드 스레드 또는 작업자 스레드도 생성하기 때문에 하루가 끝날 때 변경 사항이 없으므로 별도의 스레드를 다시 만들지 않으므로 그 점을 알아야합니다.
위의 구현과 백그라운드 스레드를 만드는 것의 차이점은 무엇입니까?
응용 프로그램의 내부 및 외부 스레드를 혼란스럽게합니다. UI 스레드에서 WaitForExit을 사용하는 경우. UI 스레드가 응답하지 않게됩니다. 문제가 발생하면 BackgroundWorker의 DoWork 이벤트에 새 프로세스를 생성하십시오. 프로세스가 종료되면 UI 스레드에 경고하는 RunWorkerCompleteEvent가 트리거됩니다.
민 주 (Min Zhu) 마이크로 소프트 우연한 직원의 답변으로 표시 중재자 Monday, July 18, 2011 3:10 AM.
Microsoft는 Msdn 웹 사이트에 대한 귀하의 의견을 이해하기 위해 온라인 설문 조사를 실시하고 있습니다. 참여를 선택하면 Msdn 웹 사이트를 탈퇴 할 때 온라인 설문 조사가 제공됩니다.
App Store를 통해 가져 오기 우리의 응용 프로그램 에서이 게시물을 읽으십시오!
Process. WaitForExit는 Process. HasExited가 true 인 경우에도 반환되지 않습니다.
Process. Start를 사용하여 배치 파일을 시작합니다. 배치 파일은 "START"명령을 사용하여 여러 프로그램을 병렬로 시작한 다음 종료합니다.
일단 배치 파일이 완료되면 Process. HasExited가 true가되고 Process. ExitCode에 올바른 종료 코드가 포함됩니다.
하지만 Process. WaitForExit ()을 호출하면 중단되거나 반환되지 않습니다.
다음 코드는 문제를 보여줍니다. 배치 파일을 만들고 시작한 다음 인쇄합니다.
다음을 인쇄해야합니다.
. 하지만 결코하지 않습니다 (HasExited가 true이고 이미 ExitCode가 있음에도 불구하고).
배치 파일에 "START"명령이 들어있을 때와 표준 출력 및 / 또는 표준 오류가 리디렉션 될 때만 발생하는 것으로 나타났습니다.
WaitForExit ()이 반환하지 않는 이유는 무엇입니까?
그러한 프로세스가 종료 될 때까지 기다리는 올바른 방법은 무엇입니까?
Process. HasExited를 폴링하는 것이 안전합니까? 아니면 다른 문제가 발생할 수 있습니까?
추신 : 나는 방금 WaitForExit (100000)을 거대한 시간 초과 (확실히 만료되지 않음)로 호출하면 프로세스가 종료 될 때 즉시 반환하는 것으로 나타났습니다. 위어드. 타임 아웃이 없으면 중단됩니다.
이것은 표준 오류 및 StandardError의 이벤트 기반 비동기 처리의 특정 구현에서 아티팩트 ( "버그"라고 말합니다) 인 것 같습니다.
나는 당신이 제공 한 코드 (훌륭한 코드 예제, 그런데! :)를 실행함으로써 문제를 쉽게 재현 할 수 있었지만, 프로세스는 실제로 무한정 멈추지 않았다는 것을 알았다. 오히려 WaitForExit ()에서 리턴 된 것은 시작된 두 개의 하위 프로세스가 모두 종료 한 후에였습니다.
이것은 Process 클래스 구현의 의도적 인 부분 인 것으로 보인다. 특히 Process. WaitForExit () 메서드에서 프로세스 핸들 자체에 대한 대기가 끝나면 stdout 또는 stderr에 대한 판독기가 만들어 졌는지 확인합니다. 그렇다면 WaitForExit () 호출의 제한 시간 값이 "무한"(즉, -1)이면 코드는 실제로 리더에서 스트림의 끝을 기다립니다.
각각의 독자는 BeginOutputReadLine () 또는 BeginErrorReadLine () 메서드가 호출 될 때만 만들어집니다. stdout 및 stderr 스트림 자체는 자식 프로세스가 닫힐 때까지 닫히지 않습니다. 그래서 그 흐름이 끝날 때까지 그 흐름이 끝날 때까지 기다리게됩니다.
WaitForExit ()은 스트림의 이벤트 기반 읽기를 시작하는 메소드를 호출했는지 여부에 따라 다르게 동작해야하며 특히 해당 스트림을 직접 읽는 것으로 WaitForExit ()이 그런 식으로 동작하지 않으면 API를 이해하고 사용하기가 훨씬 어려워지는 불일치. 나는 이것을 개인적으로 버그라고 부르지 만, Process 클래스의 구현자가이 불일치를 인식하고 그것을 의도적으로 만들었을 가능성이 있다고 생각한다.
어쨌든, 임시 해결책은 API의 이벤트 기반 부분을 사용하는 대신 StandardOutput 및 StandardError를 직접 읽는 것입니다. 물론 코드가 해당 스트림에서 대기하는 경우에도 자식 프로세스가 종료 될 때까지 동일한 차단 동작이 표시됩니다.
예를 들어 (C #은 코드 예제를 이와 같이 빨리 때리기에 충분할만큼 F #을 알지 못하기 때문에) :) :
위의 해결 방법이나 이와 유사한 방법으로 기본 문제를 해결할 수 있기를 바랍니다. Niels Vorgaard Christensen이 WaitForExit () 메서드의 문제가있는 줄로 안내해 주신 데 대해 감사 드려서이 답변을 개선 할 수있었습니다.
월터의 통나무.
. 학습하면서 글쓰기.
2011 년 11 월 18 일 금요일.
Process. WaitForExit (Int32) 문제가 발생합니다.
보시다시피, 코드는 "cmd. exe"프로세스를 시작하고 실행하려는 명령을 전달합니다.
코드에서 ping - t 8.8.8.8 명령을 사용했습니다. - t 옵션으로 인해 호스트를 멈추지 않고 ping합니다. 무슨 일이야? ping - t 명령과 함께 "cmd. exe"프로세스는 절대로 종료되지 않고 stdout 스트림을 닫지 않으므로 코드가 Output = process. StandardOutput. ReadToEnd (); 왜냐하면 모든 스트림을 읽는 데 성공하지 못하기 때문입니다.
배치 파일의 명령이 어떤 이유로 든 중단되고 위의 코드가 계속해서 몇 년 동안 작동 한 다음 명백한 이유없이 갑자기 멈추는 경우에도 마찬가지입니다.
"cmd. exe"에 첨부하는 명령이나 호출중인 프로세스가 표준 출력이나 표준 오류를 채우면 교착 상태가 발생할 수 있습니다. 이것은 코드가 라인에 도달 할 수 없기 때문입니다.
실제로 우리 프로그램이 스트림의 채워진 버퍼를 읽지 않는다면 자식 프로세스 (ping 명령 또는 배치 파일 또는 실행중인 모든 프로세스)를 실행할 수 없습니다. 코드가 프로세스가있는 줄에 매달려 있습니다. WaitForExit () : 자식 프로젝트가 종료 될 때까지 기다립니다.
두 스트림의 기본 크기는 4096 바이트입니다. 다음 배치 파일을 사용하여이 두 가지 크기를 테스트 할 수 있습니다.
No comments:
Post a Comment