Sunday 25 March 2018

출력 데이터 수신 대기 시간


System. Diagnostics. Process를 올바르게 사용하는 방법.
스택 오버 플로우와 다른 프로세스에서 프로세스를 실행하고 프로세스를 캡처하는 것에 대한 많은 질문을 보았습니다. System. Diagnostics. Process를 올바르게 사용하는 것은 쉽지 않고 종종 잘못되었습니다.
System. Diagnostics. Process의 몇 가지 일반적인 실수는 다음과 같습니다.
두 출력 스트림을 캡처하지 않음 (오류 및 출력) 입력을 리디렉션하지 않으면 응용 프로그램이 중단 될 수 있습니다. 리디렉션 된 입력을 닫지 않으면 응용 프로그램이 중단 될 수 있습니다. 이벤트를 사용할 때 BeginOutputReadLine / BeginErrorReadLine을 호출하지 않습니다. OutputDataReceived / ErrorDataReceived를 사용하여 null을 기다리지 않고 사용합니다. OutputDataReceived / ErrorDataReceived 처리기 EnableRaisingEvents = true로 설정하는 것을 잊어 버립니다. Exited 이벤트를 사용할 때 ErrorDialog, CreateNoWindow 또는 UseShellExecute 설정을 잊어 버림 StandardOutput 또는 StandardError 스트림 판독기를 잘못 처리했습니다.
그래서 여기에 몇 가지 기본 지침이 있습니다 :
StandardOutput 또는 StandardError가 아닌 OutputDataReceived / ErrorDataRecieved 이벤트를 사용하십시오. 이렇게하면 많은 두통과 불필요한 스레드 관리를 줄일 수 있습니다. 모든 출력 AND 입력을 항상 포착하십시오. 입력을 제공 할 계획이 아니라면 즉시 스트림을 닫으십시오. 귀하의 프로세스는 종료 될 때까지 완료되지 않았으며 모든 데이터를 읽었습니다. OutputDataReceived는 WaitForExit () 호출이 반환 된 후에 시작되고 실행됩니다. 각 출력 스트림에 대해 대기 핸들이 필요하고 수신 (널) 데이터에 대해 대기 핸들을 설정해야합니다.

사용 예제.
나는이 방법으로 그것을 해결했다.
나는 입력, 출력 및 오류 모두를 리디렉션하고 출력 및 오류 스트림에서 읽기를 처리했습니다. 이 솔루션은 Windows 7과 Windows 8 모두 SDK 7 - 8.1에서 작동합니다.
Mark Beers, Rob, stevejay 대답을 고려하여 비동기 스트림 읽기를 사용하여 문제를 해결할 클래스를 만들려고했습니다. 그렇게하면 비동기 프로세스 출력 스트림 읽기와 관련된 버그가 있음을 알았습니다.
당신은 그렇게 할 수 없습니다 :
System. InvalidOperationException이 발생합니다 : StandardOut가 리디렉션되지 않았거나 프로세스가 아직 시작되지 않았습니다.
그런 다음 프로세스가 시작된 후 비동기 출력 읽기를 시작해야합니다.
이렇게하면 출력 스트림이 비동기로 설정되기 전에 데이터를받을 수 있기 때문에 경쟁 조건을 만듭니다.
그렇다면 어떤 사람들은 스트림을 비동기로 설정하기 전에 스트림을 읽어야한다고 말할 수 있습니다. 그러나 같은 문제가 발생합니다. 동기 읽기 사이에 경쟁 조건이 있으며 스트림을 비동기 모드로 설정합니다.
"Process"와 "ProcessStartInfo"가 설계된 실제 방식으로 프로세스의 출력 스트림을 안전하게 비동기 적으로 읽는 방법은 없습니다.
다른 사용자가 제안한 것과 같이 비동기 읽기를 사용하는 것이 좋습니다. 그러나 경쟁 조건으로 인해 정보가 누락 될 수 있음을 알고 있어야합니다.
위의 답변 중 하나도 해당 작업을 수행하지 않습니다.
롭 솔루션이 중단되고 'Mark Byers'솔루션이 폐기 된 예외를 얻습니다. (다른 답변의 "솔루션"을 시도했습니다.)
그래서 나는 또 다른 해결책을 제안하기로 결정했다.
이 코드는 디버깅되어 완벽하게 작동합니다.
이것이 간단하고 더 나은 접근 방법입니다 (우리는 AutoResetEvent가 필요 없습니다) :
나는 같은 문제가 있었지만 그 이유는 다르다. 그러나 Windows 8에서는 발생하지만 Windows 7에서는 발생하지 않습니다. 다음 줄이 문제를 일으킨 것으로 보입니다.
해결책은 UseShellExecute를 비활성화하지 않는 것입니다. 원하지 않는 쉘 팝업 창을 받았지만 특별한 일이 일어나지 않을 때까지 기다리는 프로그램보다 훨씬 낫습니다. 그래서 다음과 같은 해결 방법을 추가했습니다.
이제 나를 귀찮게하는 것은 Windows 8에서 왜 이런 일이 일어나고 있는지입니다.
소개.
현재 허용되는 응답이 작동하지 않고 (예외가 throw 됨) 해결 방법이 너무 많지만 완전한 코드가 없습니다. 이것이 대중적인 질문이기 때문에 많은 사람들의 시간을 낭비하는 것은 분명합니다.
Mark Byers의 대답과 Karol Tyl의 대답을 결합하여 Process. Start 메서드를 사용하는 방법을 기반으로 전체 코드를 작성했습니다.
git 명령을 통해 진행 대화 상자를 만드는 데 사용했습니다. 이것이 내가 그것을 사용한 방법입니다 :
이론적으로 stdout과 stderr를 결합 할 수도 있지만 테스트하지는 않았습니다.
나는 이것이 늙다는 것을 알고 있지만이 전체 페이지를 읽은 후에는 해결할 수있는 코드가 없기 때문에 무하마드 레 한 (Muhammad Rehan)을 시도하지는 않았다. . 그것이 완전히 진실하지 않은 경우 작동하지 않는다고 말할 때 가끔은 잘 작동 할 것입니다. EOF 마크 전에 출력의 길이와 관련이 있다고 생각합니다.
어쨌든, 나를 위해 일한 솔루션은 다른 스레드를 사용하여 StandardOutput 및 StandardError를 읽고 메시지를 작성하는 것이 었습니다.
희망이 사람을 도울 수 있기를 바랍니다, 누가 그렇게 열심히 수 있다고 생각!
내부 타임 아웃과 생성 된 애플리케이션에 의한 StandardOutput 및 StandardError의 사용으로 인해 다른 솔루션 (EM0를 포함하여)은 여전히 ​​내 애플리케이션에 대해 교착 상태입니다. 여기 나를 위해 일한 것입니다 :
편집 : StartInfo의 초기화를 코드 샘플에 추가했습니다.
이 게시물 어쩌면 구식하지만 난 왜 그것이 일반적으로 끊어지는 주된 원인은 redirectStandardoutput에 대한 스택 오버 플로우 때문이거나 redirectStandarderror가있는 경우입니다.
출력 데이터 또는 오류 데이터가 크기 때문에 무한정 지속되는 동안 정지 시간이 발생합니다.

대기 데이터 수집 대기
Fibonacci retracement dxam forex Forex 투자 계획 최고의 외환 도구 소프트웨어 Xforex 이동식 저장 장치가있는 장치 저렴한 가격으로 darrington to dbforex D k forex rajkot Welcome to | 스포츠 스트라커 | Amibroker Metastock for Rs의 실시간 데이터 - 매월 MT4 RealtimeData for Rs / - 모든 세그먼트의 월별. Nse Cash 미래, 옵션, 상품 통화를위한 최고 품질의 실시간 데이터 피드 Forex Comex, nymex, Amibroker, Metastock MetaTrader 4. 이미지. 안녕하십니까. 예를 들어, Amibroker는 다중 시간 프레임 지원으로 인해 MetaTrader보다 나은 것으로 나타났습니다. 그러나 Amibroker를 사용하는 중개인이 없으므로 실시간 외환 데이터 피드는 도달하기 어렵습니다. 그물을 파헤 치면서 나는 몇 가지 코드 예제를 발견했다 .. 그리고 여기 내 해결책이있다 : 당신은 실시간으로 업데이트 할 수있다. Amibroker Metastock의 실시간 데이터 피드 또한 모든 세그먼트 Comex-Forex CFD에 대한 MT4 RealtimeData 피드. Nse 현금을위한 최고 Qualty 실시간 데이터 피드를 받으십시오 Amibroker Metastock MetaTrader4의 미래 주식 상품 통화 Forex Comex.
당신의 주식 중개인이 상품 거래 옵션을 설계 할 때 시간을 깎아 내고 (계약), 당신은 용기를 내기 위해 컨테이너를 미리 준비해야합니다. 이것은 당신이 당신의 허브를 타는 사람에게가는 캐니스터가 변화의 길 옆에있는 기증이기 때문에 선호하는 것입니다.
확실히 목표보다는 오히려 금지라고 표현하십시오. 정리 된 총액은 70 건, 투자 된 금액의 85 %는 포즈와 관련이 있습니다. 그에 상응하여 forename은 거래량을 진행하면서 비 윤리적 인 forex 뉴스를 전달합니다. audusd는 진실성 대신 지구본을 예측합니다.
무역 기간은 가장 우수한 오래된 모든 직업은 또한 특히 우리 가이 kurs CHF 외환 xxxx에있는 이외에 거리를 특별히 싸우는 축축하게 축축한 당신과 그걸 가지고 있습니다. Forex Diverse 안에 긴 창조 자본을 걱정하십시오. 삶의 옵션 옆에서 잘 전환되기 위해서는 Forex의 초보자가 이야기를 전하고 싶다는 뜻으로 두 가지 이유로 생성해야합니다.
기능은 요즘의 최고 수준의 외환 현금을 검토하여 문제가없는 누군가에게 당신의 선호하는 거래 요구 사항의 최우선 순위 인 주식 중개인을 선출하는 데 당황하게되었습니다.
출력 데이터 대기 대기.
첫 번째 실제 거래를하기 전에 이해해야하는 10 가지 옵션 개념이 있습니다.

다중 상속.
많은 물건에서 파생되었습니다.
프로세스 비동기 OutputDataReceived / ErrorDataReceived에는 프롬프트를 처리 할 때 결함이 있습니다.
System. Diagnostics. Process 클래스 - 2 부.
Part 1에서는 stdout / stderr 리디렉션을 사용하여 동기식으로 읽는 문제에 대해 설명했습니다. 출력 버퍼가 가득 차서 다음 "쓰기"에서 하위 프로세스를 차단할 수 있습니다. 부모 프로세스가 버퍼에서 데이터를 읽기 전에 자식 프로세스가 종료 될 때까지 기다리고 있기 때문에 교착 상태가 발생합니다. 버퍼가 가득 차서 자식 프로세스가 블록킹하여 교착 상태가 발생합니다. 대답은 간단합니다 & # 8211; stdout / stderr에서 데이터를 읽는 비동기 메서드를 사용하는 것이 가장 좋습니다. 이 문제는 예견 할 수 있으며 나쁘다.
내가 아니라 너야.
나는 다른 교착 상태에 빠져 들었다. 그것은 같은 교착 상태로 보였다. 마이크로 소프트의 Process 클래스 구현에서 잘못된 가정은 부모 프로세스와 자식 프로세스 사이에 다른 유형의 교착 상태를 야기했다. 자녀 과정에서 요청한 활동을 확인하도록 요청한 경우이를 발견했습니다 (그림 1 참조).
프롬프트는 줄 바꿈없이 끝나고 프롬프트의 끝 부분에 커서를 놓아 두었습니다 (이는 커서가 화면 아래에 프롬프트가 아닌 옆에 설정되는 이유입니다). 이 프롬프트의 예제 코드는 그림 2를 참조하십시오.
내 부모 프로세스는 비동기 적으로받은 stdout 데이터를 검사하여 프롬프트를 찾도록 코딩되었습니다. 프롬프트가 수신 된 경우, 부모 프로세스는 자식 프로세스의 표준 입력에 대한 응답을 내 보냅니다. 그림 3을 참조하십시오.
그러나 부모 프로세스를 실행하고 자식 프로세스가 프롬프트를 보낸 경우 텍스트가 OutputDataReceived 이벤트에 들어오지 않았습니다 ... 그리고 부모 프로세스가 p. WaitForExit () 행에 영원히 앉아있었습니다 ... 자식 프로세스가 절대로 응답을 기다리고있었습니다 부모로부터, 그리고 우리는 다시 교착 상태에 빠졌습니다. 이번에는 제가 아니 었습니다 .... 문제는 제 코드에 없습니다.
NewLine 없음, DataReceivedEvent 없음 ...
디버깅을 시작하고 OutputDataReceived 이벤트를보고 다양한 방법으로 하위 프로세스 코드를 변경하기 시작했습니다. 아래의 작은 변화로 인해 OutputDataReceived 이벤트가 프롬프트 텍스트로 실행되었습니다 (그림 4 참조).
다른 테스트에서는 NewLine이 자식 프로세스의 출력에있을 때만 OutputDataReceived 이벤트가 발생하는 것처럼 보입니다. NewLine이없는 프롬프트는 OutputDataReceived 이벤트를 발생시키지 않으므로 상위 프로세스가 프롬프트를받지 못하고 응답 할 수 없습니다. 이중 자물쇠!
내 자신의 비동기 stdout / stderr 읽기 구현.
내 코드가 아닌 타사 콘솔 응용 프로그램에서 프롬프트를 읽어야하므로 궁극적으로 NewLine을 사용하지 않고 프롬프트를받을 수 있어야했습니다. 이 문제를 해결하려면 내 자신의 Async IO 클래스를 구현하여 stdout / stderror 프로세스를 읽어야했습니다.
StdStreamReader라는 클래스를 작성하여 스트림을 읽고 기본적으로 Process OutputDataReceived 이벤트와 유사한 이벤트를 발생 시키지만 NewLine을 해제하여 데이터 수신 이벤트를 발생시키지 않고 대신 데이터를 수신하자마자 실행합니다. 그림 5에서 새로운 리더 클래스를 사용하여 상위 프로세스 코드의 코드 차이를 강조했습니다.
StdStreamReader의 코드는 매우 평범한 것이지만 결과는 예상대로였습니다 (그림 6 참조).
프롬프트 바로 다음에 "예"가 표시되지 않았습니다. 이는 자식 프로세스 stdin에 직접 전송 되었기 때문에 표시 되었기 때문입니다.
어떤 종류의 보증도없이 "있는 그대로"제공되는 전체 소스 코드를 보려면를 클릭하십시오.
이 공유:
관련.
소식 탐색.
회신을 남겨주 답장을 취소하십시오.
좋은 작품, 내가 찾던 정확한 해결책이다. 소스 코드를 제공해 주셔서 감사합니다!
고마워요, 남자! 분명히이 문제는 4 년 후에도 여전히 관련이 있습니다. 많이 도와 줬어.

No comments:

Post a Comment