2008-10-31 15 views
5

Tengo un problema de subprocesamiento con Delphi. Supongo que esto también es común en otros idiomas. Tengo un proceso largo que hago en un hilo, que llena una lista en la ventana principal. Pero si algunos parámetros cambian mientras tanto, entonces debería detener el hilo de ejecución actual y comenzar desde el principio. Delphi sugiere terminar un hilo configurando Terminated: = true y verificando el valor de esta variable en el hilo. Sin embargo, mi problema es este, la parte de ejecución larga está enterrada en una llamada a la biblioteca y en esta convocatoria no puedo verificar la variable Terminated. Por lo tanto, tuve que esperar a que terminara esta llamada a la biblioteca, lo que afecta a todo el programa.Cómo detener procesos largos de ejecución con gracia?

¿Cuál es la forma preferida de hacer en este caso? ¿Puedo matar el hilo inmediatamente?

+1

¿Qué es la llamada de larga duración de la biblioteca? –

Respuesta

3

Los hilos deben cooperar para lograr un apagado correcto. No estoy seguro de si Delphi ofrece un mecanismo para abortar otro hilo, pero tales mecanismos están disponibles en .NET y Java, pero deben considerarse como una opción de último recurso, y el estado de la aplicación es indeterminado después de que hayan sido utilizados.

Si puede matar un hilo en un punto arbitrario, puede matarlo mientras mantiene un bloqueo en el asignador de memoria (por ejemplo). Esto dejará su programa abierto para colgar cuando su siguiente hilo principal necesite acceder a ese bloqueo.

9

La forma preferida es modificar el código para que no se bloquee sin verificar la cancelación.

Como no puede modificar el código, no puede hacerlo; usted debe vivir con la operación de fondo (pero puede desasociarla de cualquier UI, de modo que se ignorará su finalización); o alternativamente, puedes intentar terminarlo (TerminateThread API terminará groseramente cualquier hilo dado su manejo). Sin embargo, la terminación no es limpia, como dice Rob, cualquier bloqueo que tenga el hilo será abandonado, y cualquier estado de hilo cruzado protegido por dichos bloqueos puede estar en estado corrupto.

¿Puede considerar llamar a la función en un archivo ejecutable por separado? ¿Quizás usar RPC (pipes, TCP, en lugar de memoria compartida debido al mismo problema de bloqueo), para que pueda finalizar un proceso en lugar de terminar un hilo? El aislamiento del proceso le dará mucha más protección. Siempre y cuando no dependa de elementos nombrados de proceso cruzado como mutexes, debería ser mucho más seguro que matar un hilo.

+0

Esto suena como un buen consejo.Hacer esta llamada en otro proceso no dejará rastros después de perderlo. – Glenner003

3

Si no puede modificar el código para verificar la terminación, simplemente establezca su prioridad muy baja e ignórela cuando vuelva.

0

escribí esto en respuesta a una similar question:

utilizo una técnica basada en excepciones que ha funcionado muy bien para mí en una serie de aplicaciones Win32 . Para terminar un hilo, uso QueueUserAPC para poner en cola una llamada a una función que lanza una excepción. Sin embargo, la excepción que se lanza no se deriva del tipo "Excepción", por lo que solo se detectará por el procedimiento de reinicio de mi hilo.

He usado esto con las aplicaciones de C++ Builder con mucho éxito. No estoy al tanto de todas las sutilezas del manejo de excepciones de Delphi vs C++, pero espero que pueda modificarse fácilmente para que funcione.

Cuestiones relacionadas