2011-03-19 22 views
6

Tengo un problema cuando la salida de la consola se devuelve en 'ondas'. Por ejemplo, la consola genera algo por segundo y, por ejemplo, el evento se dispara 60 veces por minuto (todos los eventos al mismo tiempo).Leyendo otra salida de la consola de proceso

Mi código:

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(); 

podría sospechar que hay un problema con la herramienta de actualización. Otros programas con salida de consola funcionan bien.

En línea de tiempo en que se desencadenan eventos: (= no pasó nada; | suceso activado)

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

Creo que debe enjuagar la salida. No sé cómo de todos modos – BlackBear

Respuesta

6

Está viendo el efecto del buffer de salida stdout que está usando el programa. Esta es una característica estándar de la biblioteca en tiempo de ejecución de C, el almacenamiento en búfer está habilitado cuando detecta que está escribiendo en un conducto en lugar de en la consola. En lugar de enjuagar automáticamente después de cada instrucción printf() en el programa. El buffer es generalmente de alrededor de 2 kilobytes. Y solo se enrojece cuando se llena. Esto mejora enormemente la eficiencia, el enjuague cada vez agrega mucha sobrecarga. Importante en normales redirigir escenarios, cuando la salida se escribe en un archivo o dispositivo.

Puede ver a dónde va esto, los grupos que ve son el contenido de ese búfer. No existe una solución simple para esto, se requiere cirugía en el programa para desactivar el buffer o enjuagarlo donde sea importante. Es invariablemente donde se detiene el dinero, no estarías haciendo esto si pudieras modificar el programa. Podrías alimentar por goteo tu consola almacenando en búfer lo que obtienes de OutputDataReceived, pero quizás sea un poco tonto.

No verá este efecto cuando el programa envíe resultados más rápido de lo que puede procesarlo. Lo cual es bastante común. Se acelera de forma efectiva, bloqueando mientras se espera que el buffer de salida se vacíe y lo vuelva a llenar rápidamente.

Hay una explicación más para esto, la velocidad a la que OutputReceived puede disparar también depende de la cantidad de subprocesos de subprocesos que haya ejecutado. Si eso es más que el número de núcleos de la CPU, el hilo tp que llama a OutputReceived puede retrasarse en un múltiplo de 0,5 segundos. Sin embargo, vería la agrupación en todos los programas que redirecciona.

+0

Puede que desee echarle un vistazo a esto también: http://alabaxblog.info/2013/06/redirectstandardoutput-beginoutputreadline-pattern-broken/ – Almund

0

estoy de ninguna manera familiarizado con C# pero es posible encontrar información útil con respecto a este problema mediante la búsqueda en los documentos para descarga de la consola.

Tal como esto:

Console.Out.Flush() 
0

considerar el uso de Console.Out.Flush() (y Console.Error.Flush(), si va a imprimir al problema de flujo también).

Según tengo entendido, los controladores no están escribiendo en la línea de comandos con Console.Out.Write() - escriben en un búfer que se imprimirá algo más. Con múltiples llamadas al Console.Out.Write(), todos los bufferes no se escriben a la vez; algunos textos se dejan en un búfer más tiempo que otros. Console.Out.Flush() obliga al sistema a escribir su memoria intermedia actual inmediatamente.

Cuestiones relacionadas