Thursday 16 November 2017

Espera Hasta El Fin De La Hora


El código parece casi esto: Como se puede ver, el código inicia un proceso cmd. exe y le pasa el comando que quiero que se ejecute. Redirecciono StandardError y StandarOutput para leerlos desde el código. El código los lee antes del proceso. WaitForExit (Timeout) llamada como recomendado por Microsoft (más sobre esto más adelante). El problema surge si el comando que envío a cmd. exe nunca termina o se bloquea indefinidamente. En el código he utilizado el comando ping - t 8.8.8.8 que, debido a la opción - t, pings el host sin detenerse. ¿Qué ocurre? El proceso cmd. exe junto con el comando ping - t nunca sale y nunca cierra el flujo stdout y por lo tanto nuestro código se cuelga en la línea Output. StandardOutput. ReadToEnd () porque no puede tener éxito leyendo todo el flujo. Lo mismo sucede también si un comando en un archivo por lotes cuelga por cualquier razón y por lo que el código anterior podría trabajar continuamente durante años y luego colgar de repente sin ninguna razón aparente. Antes de escribir que su recomendado para leer los flujos redirigidos antes del proceso. WaitForExit (Timeout) llamada, esto es especialmente cierto si utiliza la firma WaitForExit sin el tiempo de espera. Si llama al proceso. WaitForExit () antes de leer los flujos redirigidos: código 2: puede experimentar un interbloqueo si el comando que adjuntas a cmd. exe o el proceso que estás llamando llena la salida estándar o el error estándar. Esto porque nuestro código no puede alcanzar las líneas de proceso de salida. StandardOutput. ReadToEnd () Como cuestión de hecho el proceso hijo (el comando ping o un archivo por lotes o cualquier proceso que está ejecutando) no puede seguir si nuestro programa no lee los buffers llenos de los arroyos y esto no puede suceder porque el código está colgando en La línea con el proceso. WaitForExit () que esperará siempre para que el proyecto secundario salga. El tamaño predeterminado de ambas secuencias es 4096 bytes. Puede probar estos dos tamaños con estos archivos por lotes: El primer guión escribe 4096 bytes en la salida estándar y el segundo en el error estándar. Guarde uno de estos en C: testbuffsize. bat y ejecute nuestro proceso de llamada al programa. WaitForExit () antes de proceso de salida. StandardOutput. ReadToEnd () como en el código 2. puede hacerlo escribiendo CommandResult Resultado ExecuteShellCommandSync (c: testbuffsize. bat, 1000) en la línea 13 del código 1. El código suele pasar el rato, pero si se escribe un byte más en cualquiera de las dos corrientes que se desborde el tamaño del búfer haciendo que el programa colgar. Si necesita redirigir y leer la salida estándar o el error estándar, la mejor solución es leerlos de forma asíncrona. Una excelente manera de hacerlo es propuesta por Mark Byers en este hilo de stackoverflow. Como último aspecto, observe que si el proceso secundario sale sólo porque utiliza el proceso. WaitForExit (Timeout) de la firma y en realidad va en tiempo de espera que debe matar el proceso cmd. exe y sus posibles hijos. Mira BBC iPlayer fuera del Reino Unido, simplemente desbloquear el Internet 038 Ver todo Reino Unido 038 Contenido de EE. UU. en cualquier lugar con nuestros servidores rápidos de VPN watchbbciplayerabroad 2014 -10-02T21: 58: 1400: 00 Vea Beeb Player, ITV Player y todos los demás servicios de TV en línea de US amplificadores de EE. UU. Desbloqueados en el extranjero en cualquier lugar. Todo lo que necesitas hacer es pedir, instalar amp connect Sí, realmente es tan simple AVISO LEGAL: Este sitio web es un servicio de revisión de blog independiente, que informa a las personas de las diversas formas de acceso a la comunicación y los medios de comunicación en línea. No damos permiso a los derechos de autor ni a la elusión de la tecnología y aconsejamos a todos los lectores que obtengan permiso (s) para acceder a cualquier aplicación de streaming de medios de terceros y que cumplan con los términos de servicio de estas aplicaciones de medios de cualquier país de origen. Este sitio web no se responsabiliza de las acciones de los usuarios. AVISO: Compruebe siempre que tiene permisos locales para acceder a aplicaciones de streaming multimedia en el extranjero. Este sitio web no tiene ninguna responsabilidad sobre el acceso de los usuarios a sitios web de terceros ni el contenido de them. This cuestión puede parecer un poco extraño, pero estoy tratando de ejecutar VS2005 a través de un proceso y ejecutar un comando específico y waitforexit (). Estoy redirigiendo mi entrada y salida con éxito pero de vez en cuando sucede que recibo una Ventana Error Reporting Window / Message. El problema es que estoy remoting, así que cuando este mensaje / ventana ocurre durante la ejecución del proceso, colgaré a menos que entre en la otra máquina (remoting) y cierra la ventana. ¿Hay alguna forma de programaticamente matar esta ventana o, posiblemente, deshabilitar el mensaje / ventana que se producen He pensado en ejecutar VS en una ejecución silenciosa (todavía tengo que encontrar una manera de hacerlo). También he intentado ver si hay algo que se lauched cuando ocurre esto se compara a cuando no lo hace. Thursday, October 25, 2007 8:32 PM Respuestas Bueno, he intentado usar FindWindow y FindWindowEx junto con SendMessage pero no pude encontrar el identificador de ventana correcto. Pero ya que sé que una caja de Msssage del informe de error de Windows aparecerá, comprobé para ver si era su propio proceso (y él es). El proceso es dwwin. exe (Dr. Watson Win) y todo lo que tenía que hacer era permitirme corregir el problema actual. Sustituya el bloque de código actual a continuación para la sentencia WaitForExit () que tenía anteriormente. Proc. WaitForExit (60000) // un minuto Proceso ProcArray Process. GetProcessesByName (quotdwwinquot) foreach (Proceso ProcessFound en ProcArray) También he comprobado para ver si era capaz de obtener el Process. MainWindowTitle (), pero se establece en quotquot. Así que esto es un hack y realmente no me gusta usarlo, pero funciona para la ejecución actual. Monday, October 29, 2007 7:26 PM No, puedo redirigir la entrada y la salida sin ningún problema. El error que estoy recibiendo es el informe general de errores de Windows y, por desgracia, está en japonés, así que no sé cuál es el error exacto, pero es el error general. No tengo el código delante de mí sino que fijé delegados / hilos para leer redireccionado el error y la salida después de que salga del proceso entero. No puedo llegar a nada y soy capaz de ejecutar el mismo proceso en mi propio ordenador, pero no soy capaz de hacer este comando en particular a través de la comunicación remota. Voy a probarlo mañana remoting en una máquina no japonesa en el trabajo y voy a publicar mis descubrimientos de todos modos. Friday, October 26, 2007 2:34 AM ¿Está ejecutando la consola quotcmdquot. Si es así entonces usted tiene que mecanografiar la salida también. Si usted tiene una idea de cuánto tiempo su proceso va a tomar, entonces usted puede usar bool exitted process. WaitForExit (timeInMilliSeconds) if (exitted) // Proceso de salida antes del período de tiempo de espera. Else // Imprimir mensaje de error Esto puede no estar relacionado con lo que estás haciendo, pero tuve una experiencia donde el proceso no saldría si redirigía su salida. Intente desactivar el redireccionamiento de salida y ver si el proceso sale. Pruébalo, podría funcionar. Friday, October 26, 2007 11:58 AM Me gustaría probar eso, pero es demasiado de un hack. Tengo demasiados comandos diferentes que toman diferentes cantidades de tiempo (30 segundos a 25 minutos) por lo que no hay ajuste de tiempo real que podría colocar sin destruir mi rendimiento. Esta función ha estado funcionando correctamente para varios comandos durante los últimos 6 meses y ahora se decide a salir en mí. Lo intenté en una computadora diferente sin ningún problema (que está realmente ensuciando conmigo). Sé que no es la redirección de salida / error porque se está creando una nueva WINDOW en el servidor al que estoy remoting. Tan pronto como cierre esa ventana, mi proceso sale como se esperaba y la salida correcta se muestra en el lado del usuario. Gracias por su ayuda, pero estoy muy frustrado con este problema. Friday, October 26, 2007 3:01 PM Sin saber el detalle del mensaje era sólo adivinar el problema. ¿Ha instalado. NET 3.5 beta o beta de Visual Studio 2008 en absoluto ¿Cómo está utilizando Process para iniciar el programa, Process. Start (quotfile. exequot), o está utilizando ProcessStartInfo Friday, October 26, 2007 3:21 PM No, Tengo. NET 2003 y. NET 2005 instalado. Proc nuevo Process () procSI nuevo ProcessStartInfo () A continuación, configurar un nuevo hilo para el StandardError y StandardOutput A continuación, escribir mis comandos y si (reorientación estándar) Out Si (redireccionamiento del error estándar) Inicie el hilo para st. Error Proc. WaitForExit () lt -------- este es el lugar donde se genera la ventana de Windows Error Reporting. Traduje lo que pude de la Ventana que aparece. Microsoft Visual Studio 2005 Debido a que el problema ocurre, termina Microsoft Visual Studio 2005. Estamos aplicando inconvenientes, no hay excusa. Gracias de nuevo por todo su tiempo. Creé el StreamWriter sIn antes de crear el objeto proc Process. A continuación, redirigir la entrada después del comando proc. Start (), así que ¿cómo no tengo este Independientemente, puedo hacer el cambio para mover el sIn. Close () a después de la llamada WaitForExit para ver si esto hace que los cambios. El Proc era un tipo, debería haber sido proc. Una vez más, no es un mensaje de error, por lo que no hay rastro de la pila. Mi redirección StandardError está vacía y el redireccionamiento Standard OUtput contiene lo que esperaba, pero no aparece nada que indique un error. Esto es por qué todo sigue funcionando después de cerrar la ventana de informes de errores de Windows. Publicaré lo que sucede después de mover la línea sIn. Close () debajo de la línea WaitForExit (). Viernes, 26 de octubre de 2007 16:59 Peter Ritchie escribió: Usted no quiere cerrar el objeto sIn hasta después de que la aplicación ha salido si youre redireccionamiento. Uno no debe cerrar ninguno de esos arroyos en absoluto. El objeto Proceso los posee y es el responsable de la limpieza después de sí mismo. Uno debe llamar a Process. Dispose () después de terminar con el objeto de proceso. Usted ciertamente no necesita (es decir, su redundante), pero no debería causar un problema después de que el proceso ha salido. Process. Close es el método recomendado para cerrar los flujos standardinput y standardoutput (y standarderror). Friday, October 26, 2007 5:03 PM Me sorprendería si el método de Dispose no llamaba Close, al menos como parte de su operación. Me gustaría utilizar el hecho de que, puesto que el proceso implementa IDisposable (indirectamente a través de extender el componente que lo implementa), uno debe invocar Dispose y dejar que a la limpieza adecuada. No recomendaría invocar Process. Close en lugar de, ni tampoco, Process. Dispose. Sí, Dispose llamadas Cerrar. Mi primera recomendación es usar un bloque de uso, mi segundo es llamar a Close cuando sabes cuando terminaste con él. En objetos que implementan un método quotClosequot a pesar de ser IDisposable, es mucho más claro usar el método quotClosequot. Además, sin utilizar un bloque de uso, no tiene forma de determinar el alcance de la variable y la llamada a Dispose: el objeto podría utilizarse después de la llamada a Dispose. Si utiliza Close youve, eliminó todos sus recursos administrados pero el objeto todavía se puede usar (es decir, no ha sido marcado como quotdisposedquot y puede utilizarlo para ejecutar otra aplicación sin asignar un nuevo objeto Process - que de otro modo lanzaría ObjectDisposedException ). Por lo tanto, si la primera recomendación es usar un bloque de uso, entonces lo mejor sería llamar a Dispose. No Cierra, cuando, como dijiste, sabes que has terminado con el objeto. Al solo llamar a Close en algo que implemente IDisposable, el desarrollador está potencialmente cometiendo un error. Si Dispose realiza alguna limpieza adicional más allá de la delegación en Cerrar, el programador se prepara para un error llamando a Cerrar. Puede haber un caso para llamar a Close, pero solo si no has terminado con el objeto, como indicaste al final de tu última respuesta. Pero cuando termine con él, llame a Dispose. Por lo tanto, si la primera recomendación es usar un bloque de uso, entonces lo mejor sería llamar a Dispose. No Cierra, cuando, como dijiste, sabes que has terminado con el objeto. Al solo llamar a Close en algo que implemente IDisposable, el desarrollador está potencialmente cometiendo un error. Si Dispose realiza alguna limpieza adicional más allá de la delegación en Cerrar, el programador se prepara para un error llamando a Cerrar. Puede haber un caso para llamar a Close, pero solo si no has terminado con el objeto, como indicaste al final de tu última respuesta. Pero cuando termine con él, llame a Dispose. En realidad, su quotmorequot equivalente a: DisposableClass obj nuevo DisposableClass () IDisposable descartable obj como IDisposable si (disponible null) Pero sí, eso es lo que una sentencia using es quotfuncionalmente equivalentequot a pero no estoy de acuerdo llamando explícitamente Dispose en la presencia de un método quotClosequot debe Ser la primera opción debido a la falta de alcance con la llamada Dispose. Por ejemplo, lo siguiente: using (Process process new Process ()) Tenía el servicio funcionando, pero lo detuve porque se había ejecutado durante 2 horas y nunca había el punto de interrupción que debería haber golpeado dentro de 10 minutos de mi inicio de mi cliente. He descomentado la línea sIn. Close () justo ahora y reiniciado el servicio y el cliente y todo está funcionando como lo hizo antes. Puedo golpear el punto de interrupción después de WaitForExit () y completo, con el mensaje del informe de error de Windows todavía (como era antes). Por lo tanto, en mi caso, necesito cerrar el flujo de entrada para poder salir del proceso como se esperaba. ¿Hay alguna otra idea que pueda recomendar la línea sIn. Close () si desea comprobar algo. Viernes, 26 de octubre de 2007 7:19 Anthony Maimone escribió: Tenía el servicio en funcionamiento, pero lo detuve porque había funcionado durante 2 horas y nunca había el punto de interrupción que debería haber golpeado dentro de 10 minutos de empezar mi cliente . He descomentado la línea sIn. Close () justo ahora y reiniciado el servicio y el cliente y todo está funcionando como lo hizo antes. Puedo golpear el punto de interrupción después de WaitForExit () y completo, con el mensaje del informe de error de Windows todavía (como era antes). Por lo tanto, en mi caso, necesito cerrar el flujo de entrada para poder salir del proceso como se esperaba. ¿Hay alguna otra idea que pueda recomendar la línea sIn. Close () si desea comprobar algo. Sería útil ver los detalles de excepción cuando obtenga el error (como la pila de llamadas). ¿Cómo está utilizando la entrada estándar y la salida estándar? ¿Está utilizando cualquier método de ReadLine? Peter, mi punto es: Si usted no llama a Dispose en un objeto que implementa (directa o indirectamente) IDisposable, entonces está pidiendo un error. No quiero discutir sobre esto sin fin, sin embargo. Usted puede seguir haciéndolo de la manera en que lo hace, y yo me quedo con la mía. Mientras no tengamos que mantener el código de cada uno, bien. Y por cierto, un bloque quotusingquot no te protege tampoco. Nada lo impide declarar la variable fuera del bloque (si recuerdo correctamente), por lo que todavía puede estar en el ámbito después de que el bloque termina. Usted tiene que ser diligente en escribir el código correcto. Si usted lo declara en la declaración quotusingquot, eso es una manera. Pero descartar usando el método try / finally sólo porque deja la variable en el ámbito no es realmente el punto. Todavía necesita ser Dispose () d en alguna parte. El viernes 26 de octubre de 2007 7:34 Peter Ritchie escribió: Anthony Maimone escribió: Tenía el servicio en funcionamiento, pero lo detuve porque había funcionado durante 2 horas y nunca había el punto de interrupción que debería haber golpeado en 10 minutos de Yo empezando mi cliente. He descomentado la línea sIn. Close () justo ahora y reiniciado el servicio y el cliente y todo está funcionando como lo hizo antes. Puedo golpear el punto de interrupción después de WaitForExit () y completo, con el mensaje del informe de error de Windows todavía (como era antes). Por lo tanto, en mi caso, necesito cerrar el flujo de entrada para poder salir del proceso como se esperaba. ¿Hay alguna otra idea que pueda recomendar la línea sIn. Close () si desea comprobar algo. Sería útil ver los detalles de excepción cuando obtenga el error (como la pila de llamadas). ¿Cómo se utiliza la entrada estándar y la salida estándar ¿Está utilizando cualquier método ReadLine? Una vez más, esto NO es una Excepción que se está lanzando, por lo que no estoy viendo detalles de la excepción. No voy directamente al bloque de la captura en mi código, reanudo DIRECTAMENTE después de la llamada de WaitForExit (). La ventana que estoy recibiendo es la misma que obtienes cuando CUALQUIER producto de Microsoft cierra inesperadamente y MS quiere información sobre el Crash. Así que de nuevo, no hay detalles de excepción. Sin embargo, en uno de los Registros del sistema, estoy recibiendo un mensaje (traducido desde el japonés) errores de aplicación quotDevenv. exe ocurren, 8.0.50727.762 versión de los errores ocurridos msvcr80.dll módulo, versión 8.0.50727.762, se produjeron errores dirección 0x00039001. Para más información, go. microsoft/fwlink/events. asp el Helo y el Centro de Soporte por favor refer. quot Estoy redirigiendo la entrada Estándar para pasar en los diferentes comandos en porque estaba teniendo problemas para que funcionen cómo quería formar el StartInfo . Estoy redirigiendo los flujos de salida y error para comprobar lo que tienen en ellos después de que el proceso ha salido. Esto me permitirá comprobar cualquier cosa que me gustaría en cualquier flujo una vez que hemos terminado. También no permito que ninguno de los subprocesos de redirección de salida o error se unan hasta después de que el proceso ha pasado la llamada WaitForExit. Estoy completamente perplejo. Peter, mi punto es: Si usted no llama a Dispose en un objeto que implementa (directa o indirectamente) IDisposable, entonces usted está pidiendo un error. No quiero discutir sobre esto sin fin, sin embargo. Usted puede seguir haciéndolo de la manera en que lo hace, y yo me quedo con la mía. Mientras no tengamos que mantener el código de cada uno, bien. No estoy de acuerdo. No es un quotbugquot para no llamar Dispose. Sus recursos no serán liberados de inmediato, pero el GC los liberará si necesita la memoria (suponiendo que el patrón Dispose se implementa correctamente y existe un finalizador). Si la clase que está usando implementa un método quotClosequot que no hace todas las mismas cosas que quotDisposequot, Close debe ser documentado como tal o theres un error en la clase. Nunca he encontrado una clase de marco que implementa IDisposable y un método Close () que introdujo un quotleakquot cuando se llamó Close sin llamar a Dispose. El patrón abrumador de Dispose / Close es que Dispose llama Close así como el establecimiento de un indicador quotdisposedquot (utilizado para lanzar ObjectDisposedException). De hecho, esto se detalla en la Referencia general de. NET Framework: quotOcasionalmente, un nombre específico de dominio es más apropiado que Dispose. Por ejemplo, un encapsulamiento de archivos podría utilizar el nombre de método Close. En este caso, implemente Dispose en forma privada y cree un método Close público que llame a Dispose. El siguiente ejemplo de código ilustra este patrón. Puede reemplazar Cerrar con un nombre de método apropiado para su dominio. De implementar Finalizar y disponer para limpiar los recursos no administrados Además de quotPara ciertas clases de objetos, como archivos o objetos de conexión de base de datos, un método Close representa mejor la operación lógica que Debe realizarse cuando el consumidor de objetos está terminado con el objeto. todos los casos bien escritos, ambos son funcionalmente equivalentes. Esto implica que el uso de Close es más claro con quotbetter representaquot.) Y por cierto, un bloque quotusingquot no te protege tampoco. Nada lo impide declarar la variable fuera del bloque (si recuerdo correctamente), por lo que todavía puede estar en el ámbito después de que el bloque termina. Usted tiene que ser diligente en escribir el código correcto. Si usted lo declara en la declaración quotusingquot, eso es una manera. Pero descartar usando el método try / finally sólo porque deja la variable en el ámbito no es realmente el punto. Todavía necesita ser Dispose () d en alguna parte. Sí, theres todo tipo de maneras que usted puede disparar en el pie, pero eso no es un escenario que estábamos discutiendo. Yo personalmente derribar cualquier código que he revisado así. Eso estaría en mi lista no recomendada. Friday, October 26, 2007 7:54 PM Una vez más, esto NO es una Excepción que se está lanzando, así que no estoy viendo detalles de excepción. No voy directamente al bloque de la captura en mi código, reanudo DIRECTAMENTE después de la llamada de WaitForExit (). La ventana que estoy recibiendo es la misma que obtienes cuando CUALQUIER producto de Microsoft cierra inesperadamente y MS quiere información sobre el Crash. Así que de nuevo, no hay detalles de excepción. Sin embargo, en uno de los Registros del sistema, estoy recibiendo un mensaje (traducido desde el japonés) errores de aplicación quotDevenv. exe ocurren, 8.0.50727.762 versión de los errores ocurridos msvcr80.dll módulo, versión 8.0.50727.762, se produjeron errores dirección 0x00039001. Para más información, go. microsoft/fwlink/events. asp el Helo y el Centro de Soporte por favor refiérase. Asumí que su aplicación estaba generando el mensaje (en cuyo caso siempre debería obtener una excepción y un rastro de pila) no estaba claro que usted Reanudar después de la llamada a WaitForExit (). Suena a mí como la aplicación que está ejecutando está terminando de manera anormal. ¿Está ejecutando devenv. exe? No estoy seguro de lo que puede hacer en su aplicación para impedir que otra aplicación termine de manera anormal. Anthony Maimone escribió: Estoy redirigiendo la entrada estándar para pasar en los diferentes comandos en porque estaba teniendo problemas para que funcionen cómo quería formar el StartInfo. Estoy redirigiendo los flujos de salida y error para comprobar lo que tienen en ellos después de que el proceso ha salido. Esto me permitirá comprobar cualquier cosa que me gustaría en cualquier flujo una vez que hemos terminado. También no permito que ninguno de los subprocesos de redirección de salida o error se unan hasta después de que el proceso ha pasado la llamada WaitForExit. Estoy completamente perplejo. Usted puede obtener un punto muerto si bloquea en la lectura de y la salida estándar de aplicaciones - que desbloquearía si cerró el flujo, creo. Lo único que se me ocurre es crear una aplicación que se ejecute en el servidor y monitorear las ventanas que vienen formando los procesos que está controlando de forma remota y luego encontrar los botones correctos y presionarlos de forma programática enviando un mensaje a la bomba de mensaje de la ventana de diálogo . Esto ocurre con excel, word y otras aplicaciones que se pueden utilizar con autimation MSFT no diseñó estas aplicaciones para ser ejecutadas sin la interacción del usuario de manera que de vez en cuando obtendrá Windows en los errores. ¿Ha considerado el uso de MSBuid que es más apropiado para las compilaciones por lotes, también parece que en los servidores de construcción TFS 2008 será fácil de construir. Sábado, 27 de octubre de 2007 11: 07 Bueno, intenté utilizar FindWindow y FindWindowEx junto con SendMessage pero no pude encontrar el identificador de ventana correcto. Pero ya que sé que una caja de Msssage del informe de error de Windows aparecerá, comprobé para ver si era su propio proceso (y él es). El proceso es dwwin. exe (Dr. Watson Win) y todo lo que tenía que hacer era permitirme corregir el problema actual. Sustituya el bloque de código actual a continuación para la sentencia WaitForExit () que tenía anteriormente. Proc. WaitForExit (60000) // un minuto Proceso ProcArray Process. GetProcessesByName (quotdwwinquot) foreach (Proceso ProcessFound en ProcArray) También he comprobado para ver si era capaz de obtener el Process. MainWindowTitle (), pero se establece en quotquot. Así que esto es un hack y realmente no me gusta usarlo, pero funciona para la ejecución actual. Lunes 29 de octubre de 2007 19:26

No comments:

Post a Comment