2011-03-19 4 views
6

콘솔 출력이 '파도'로 반환되면 문제가 있습니다. 예를 들어, 콘솔은 매 초마다 무언가를 출력합니다. 예를 들어, 매분 60 번 (동시에 모든 이벤트)의 이벤트 트리거가 있습니다.다른 프로세스 콘솔 출력 읽기

내 코드 :

Process Proc = new Process(); 
Proc.StartInfo.FileName = SSMS.BinaryDir + "HldsUpdateTool.exe"; 
Proc.StartInfo.Arguments = "-command update -game tf -dir " + SSMS.RootDir + Key; 
Proc.StartInfo.UseShellExecute = false; 
Proc.StartInfo.RedirectStandardOutput = true; 
Proc.StartInfo.RedirectStandardError = true; 

Proc.EnableRaisingEvents = true; 
Proc.StartInfo.CreateNoWindow = false; 

Proc.ErrorDataReceived += new DataReceivedEventHandler(Proc_ErrorDataReceived); 
Proc.OutputDataReceived += new DataReceivedEventHandler(Proc_OutputDataReceived); 
Proc.Exited += new EventHandler(Proc_Exited); 

Proc.Start(); 
Proc.BeginErrorReadLine(); 
Proc.BeginOutputReadLine(); 

내가 업데이트 도구에 문제가 있다고 의심 할 수도 있습니다. 콘솔 출력이있는 다른 프로그램도 정상적으로 작동합니다.

타임 라인에서

이벤트가 트리거됩니다 : (= 아무 일도; | 이벤트 해고)

Should be: ==|==|==|==|==|==|== 
Is: ========|||||||=========||||||===== 
+0

출력을 플러시해야한다고 생각합니다. 어쨌든 어떻게 될지 모르겠다. – BlackBear

답변

6

프로그램에서 사용중인 stdout 출력 버퍼의 효과가 나타납니다. 이것은 C 런타임 라이브러리의 표준 기능으로, 버퍼링은 콘솔 대신 파이프에 쓰고 있음을 감지하면 활성화됩니다. 프로그램의 각 printf() 문 다음에 자동으로 플러시하는 대신. 버퍼는 보통 약 2 킬로바이트입니다. 그리고 그것이 가득 찼을 때만 씻겨집니다. 이렇게하면 효율성이 크게 향상되고 매번 시간이 지나면 많은 오버 헤드가 발생합니다. 중요 리디렉션 시나리오에서 출력이 파일이나 장치에 기록 될 때 중요합니다.

어디로 가는지 확인할 수 있습니다. 볼 수있는 덩어리는 해당 버퍼의 내용입니다. 이것에 대한 간단한 해결책은 없으며, 프로그램에서 버퍼를 비활성화하거나 문제가있는 곳에서 플러시하는 수술이 필요합니다. 변함없이 멈추는 곳입니다. 프로그램을 바꿀 수 있다면이 일을하지 않을 것입니다. OutputDataReceived에서 가져온 것을 버퍼링하여 콘솔을 똑똑 떨어 뜨릴 수는 있지만 어리석은 것 같습니다.

프로그램이 처리 할 수있는 것보다 빠르게 출력을 보낼 때이 효과가 표시되지 않습니다. 어느 것이 꽤 흔합니다. 효과적으로 출력 버퍼가 비워지기를 기다리는 동안 차단되어 다시 채워집니다.

또 다른 설명이 있습니다. OutputReceived가 실행되는 속도는 실행중인 스레드 풀 스레드의 수에 따라 다릅니다. 이것이 CPU 코어 수보다 많으면 OutputReceived를 호출하는 tp 스레드가 0.5 초의 배수만큼 지연 될 수 있습니다. 그러나 리디렉션하는 모든 프로그램에서 덩어리를 볼 수 있습니다.

+0

이걸보고 싶을 수도있다. http://alabaxblog.info/2013/06/redirectstandardoutput-beginoutputreadline-pattern-broken/ – Almund

0

나는 C#을 잘 알고 결코 해요하지만 당신은 문서를 검색하여이 문제에 관한 유용한 정보를 찾을 수 있습니다 콘솔 플러시. 어쩌면이 같은

: (당신은뿐만 아니라 스트림 오류에 인쇄하는 경우, 그리고 Console.Error.Flush())

Console.Out.Flush() 
0

Console.Out.Flush()을 사용하는 것이 좋습니다.

제가 알고 있듯이, 핸들러는 Console.Out.Write()과 함께 명령 행에 쓰지 않습니다. 핸들러는 다른 것이 처리하는 버퍼에 쓰고 있습니다. Console.Out.Write()을 여러 번 호출하면 모든 버퍼가 동시에 쓰여지지 않습니다. 일부 텍스트는 다른 버퍼보다 ​​긴 버퍼에 남아 있습니다. Console.Out.Flush()은 시스템에 현재 버퍼를 즉시 쓰도록합니다.