2010-10-02 19 views
8

Esta pregunta se ha formulado más de una vez, pero no he encontrado una respuesta satisfactoria en ninguna de esas discusiones.Cómo deshabilitar el almacenamiento en búfer de salida en Process.StandardOutput

Estoy iniciando un proceso de línea de comandos que produce una medida en tiempo real para STDOUT, produciendo un nuevo resultado aproximadamente cada segundo. El uso de System.Diagnostics.Process.StandardOutput produce un retraso completamente inaceptable (más de 20 segundos) a medida que los datos STDOUT funcionan a través del búfer 4k en Process.StandardOutput StreamReader, y no parece haber ninguna forma de evitar esto.

Llamando a Process.StandardOutput.BaseStream.Flush() no funciona.

He intentado hacer una lectura sincrónica byte a byte de Process.StandardOutput, pero todavía estoy 4k detrás de la salida real.

Al menos alguien puede verificar que es posible de alguna manera superar todos los problemas de almacenamiento en búfer que estoy teniendo con la redirección de STDOUT, y recibir los datos en mi aplicación tan pronto como hubiera aparecido en la ventana del shell? ¿Puedo heredar de la clase Process y cambiar cómo se comporta el streamreader StandardOutput? ¿Debo estar mirando las llamadas WINAPI sin procesar?

De alguna manera, esto tiene que hacerse, incluso si termino escribiendo C++ no administrado para iniciar la tarea y consumir la salida, y vincular eso. Cualquier ayuda es muy apreciada; Estoy en mi ingenio ...

Editar: Parece que lo que necesito es una implementación .Net de las bibliotecas "esperar" que están disponibles para C/C++, Perl, Python y Java (esas son los únicos que he encontrado hasta ahora). ¿Alguien sabe si existe tal bestia?

+0

es una mierda que nunca se obtuvo una buena respuesta a esta pregunta ... –

+0

Sí. Terminé adquiriendo el código fuente para el comando externo, y recompilando con un lavado de buffer STDOUT explícito. Sin embargo, me gustaría resolver el problema original. Jugué a escribir una implementación de .Net Expect, pero volver a compilar la herramienta externa me pareció una mejor manera de evitar que mi jefe me gritara. –

+0

He estado luchando con el mismo problema. Estoy leyendo la salida de la consola en una secuencia separada (o en realidad 2: 1 para stderr, 1 para stdout). Como resultado, el StandardOutput solo almacena en búfer cuando estás usando llamadas como 'Peek', que devolverá -1 en el proceso. Si simplemente usa 'ReadLine' o' Read' con 1 byte, funcionará muy bien, y no tendrá problemas con el almacenamiento en búfer. – atlaste

Respuesta

1

"[¿Hay alguna forma de lanzarlo de manera tal que no se dé cuenta de que se está redirigiendo?" SÍ: ese es exactamente el dominio de Expect. No conozco ninguna implementación de .Net; Sin embargo, seguramente es factible ...

+0

¡Muy desafiante debido a la forma en que Windows funciona internamente! (Bueno, no con Mono en Unix donde tienes acceso a terminales virtuales reales, pero esa es otra historia). Esperar que Windows use algún tipo de modo de depuración para hacer que todo funcione, y AIUI fue realmente un hack grave. Probablemente sería más fácil usar el propio 'expect' real (ejecutando el script' unbuffer') en un subproceso; sí, hace que la implementación sea más difícil, pero * does * tiene una muy buena posibilidad de funcionar. Excepto con 'telnet.exe'; ese es un caso especial (y extra-sucky). –

Cuestiones relacionadas