Pregunta

Estoy escribiendo una aplicación para iniciar y controlar otras aplicaciones en C#.Estoy usando el Sistema.Los diagnósticos.Clase de proceso para iniciar aplicaciones y, a continuación, supervisar las aplicaciones con el Proceso.Responder propiedad para sondear el estado de la aplicación de cada 100 milisecs.Yo uso el Proceso.CloseMainWindow para detener el Proceso o aplicación.Matar a matar si no de responder.

He notado un comportamiento extraño en donde a veces el objeto de proceso entra en un estado donde la respuesta de la propiedad siempre devuelve true incluso cuando el proceso subyacente se bloquea en un bucle y donde no responder a CloseMainWindow.

Una manera de reproducir es para sondear la Respuesta de la propiedad inmediatamente después de iniciar el proceso de instancia.Así, por ejemplo,

_process.Start();
bool responding = _process.Responding;

reproducir el error de estado, mientras que

_process.Start();
Thread.Sleep(1000);
bool responding = _process.Responding;

va a trabajar.La reducción del período de sueño a 500 introducirá el estado de error de nuevo.

Algo en llamar _process.Responder demasiado rápido después de la partida parece prevenir el objeto de obtener el derecho de cola de mensajes de windows controlador.Supongo que tengo que esperar a que _process.Empezar a terminar haciendo es asincrónico de trabajo.Hay una manera mejor esperar a que este de Subproceso de llamada.El sueño ?No estoy demasiado seguro de que el 1000 ms siempre será suficiente.

¿Fue útil?

Solución

Ahora, tengo que revisar esto más tarde, pero estoy seguro que no es un método que indica el hilo que esperar hasta que esté listo para la entrada.Eres el monitoreo de la GUI de los procesos de sólo?

No Proceso.El método waitforinputidle de ninguna ayuda para usted?O me estoy perdiendo el punto?:)

Actualización

Después de un chit-chat en Twitter (o tweet-tweet?) con Mendelt pensé que debo actualizar mi respuesta por lo que la comunidad es plenamente consciente..

  • WaitForInputIdle sólo funcionará en las aplicaciones que tienen una interfaz gráfica de usuario.
  • Especifique el tiempo de espera, y el método devuelve un valor booleano si el proceso llega a un estado de inactividad dentro de ese marco de tiempo, obviamente, puede utilizar este bucle si es necesario, o manejar como sea apropiado.

Espero que ayude :)

Otros consejos

Creo que puede ser mejor para mejorar el cheque para _process.Responder de modo que sólo se trate de detener o matar el proceso, si la Respuesta de la propiedad devuelve false durante más de 5 segundos (por ejemplo).

Creo que usted puede encontrar que muy a menudo, las aplicaciones pueden ser "no responde" por una fracción de segundo, mientras que ellos están haciendo más intensivo de procesamiento.

Creo que un enfoque más indulgente que va a funcionar mejor, lo que permite un proceso de "no responde" para una cantidad de tiempo corta, sólo de tomar acción si es repetidamente "no responde" durante varios segundos (o el tiempo que quieras).

Nota:La documentación de Microsoft indica que la Respuesta de la propiedad se refiere específicamente a la interfaz de usuario, es por eso que un recién iniciado proceso pueden no tener la interfaz de usuario de responder inmediatamente.

Gracias por las respuestas.Este

_process.Start();
_process.WaitForInputIdle();

Parece resolver el problema.Todavía extraño, porque de Responder y el método waitforinputidle en caso de que ambos utilizan la misma llamada a la api win32 debajo de las cubiertas.

Poco más de información de antecedentes
Aplicaciones GUI tiene una ventana principal con un mensaje de la cola.De responder y el método waitforinputidle de trabajo mediante la comprobación de si el proceso sigue los procesos de mensajes de la cola de mensajes.Esta es la razón por la que sólo funcionan con la interfaz gráfica de las aplicaciones.De alguna manera parece que la vocación de Responder demasiado rápido interfiere con la obtención de la el Proceso de conseguir una manija para que la cola de mensajes.Llamando el método waitforinputidle parece resolver el problema.

Voy a tener que sumergirse en el reflector para ver si me pueden dar sentido a esto.

actualización
Parece que recuperar el identificador de ventana asociada con el proceso que se acaba después de comenzar es suficiente para desencadenar el comportamiento extraño.Como este:

_process.Start();
IntPtr mainWindow = _process.MainWindowHandle;

He comprobado con Reflector y esto es lo que Responde lo hace bajo las sábanas.Parece que si usted consigue el MainWindowHandle demasiado pronto consiga el mal y se utiliza este identificador incorrecto para el resto de la vida de el proceso o hasta que usted llamar a Refresh();

actualización
Llamando el método waitforinputidle() sólo resuelve el problema, algunas de la época.Llamar a Actualizar() cada vez que lea la Respuesta de la propiedad parece funcionar mejor.

Yo también me di cuenta de que en un proyecto de unos 2 años.Me llama .Refresh() antes de solicitar cierta la proposición de valores.Fue un ensayo-y-error de enfoque para encontrar cuando tenía que llamar .Refresh().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top