2010-10-28 37 views
20

En delphi, un método en TThread se termina. Parece que un subhebra no puede matar a otro subproceso al llamar a terminación o libre. Por ejemplo A (forma principal), B (una unidad de subprocesos), C (otra forma).Cómo matar un hilo en delphi?

B está enviando datos al formulario principal y C (llamando syncronize), tratamos de poner fin a B dentro de C, mientras que B está ejecutando llamando B.terminate. Pero este método no funciona y B sigue funcionando hasta que termina en el método de ejecución.

Por favor ayuda. Gracias de antemano.

Respuesta

41

usted tiene que comprobar para terminar en el hilo para que esto funcione. Por ejemplo:

procedure TMyThread.Execute; 
begin 
    while not Terminated do begin 
    //Here you do a chunk of your work. 
    //It's important to have chunks small enough so that "while not Terminated" 
    //gets checked often enough. 
    end; 
    //Here you finalize everything before thread terminates 
end; 

Con esto, se puede llamar

MyThread.Terminate; 

y va a terminar tan pronto como se termina de procesar otro pedazo de trabajo. A esto se le llama "finalización elegante del hilo" porque el hilo en sí tiene la oportunidad de terminar cualquier trabajo y prepararse para la finalización.

hay otro método, llamado 'terminación forzosa'. Puede llamar a:

TerminateThread(MyThread.Handle); 

Al hacer esto, Windows detiene con fuerza cualquier actividad en el hilo. Esto no requiere la verificación de "Terminado" en la secuencia, pero potencialmente puede ser extremadamente peligroso, porque estás matando el hilo en el medio de la operación. Su aplicación puede bloquearse después de eso.

Es por eso que nunca usa TerminateThread hasta que esté absolutamente seguro de que tiene todas las posibles consecuencias descubierto. Actualmente no lo haces, así que usa el primer método.

+1

Gracias Timo. Respuesta clara y ejemplos. – Dylan

+0

Y gracias a ti mismo. un muy buen ejemplo. – Dylan

+3

No solo se puede bloquear la aplicación, sino que los recursos utilizados por thead no se desasignarán. TerminateThread() es una llamada de "ratio extrema". –

12

Terminar no matar a un hilo; establece la propiedad Terminated para informar al hilo que debe terminar. Es responsabilidad del hilo mirar Terminated y apagarse con elegancia.

3

Todo el método Terminate hace es establece la propiedad Terminated en verdadero. Por lo tanto, debe seguir comprobando manualmente esa propiedad y luego salir del método de subproceso cuando se establece en verdadero.

0

Si es posible que desee dar por terminado un hilo, entonces podría ser mejor desove otra aplicación y matando a que si usted piensa que sus fallidos - A continuación, Windows poner en orden después de usted.

14

En realidad,

actualmente más votada respuesta a esta pregunta no es correcta (con el fin de 34 upvoters ...) en lo que se refiere a cómo matar a la fuerza de un hilo.

Usted no use ThreadId como un parámetro para el procedimiento TerminateThread. El uso de ThreadId causará probablemente un error de "identificador no válido" o en el peor de los casos scenerio - matará un hilo diferente.

Debe pasar una thread handle como parámetro:

TerminateThread(MyThread.Handle); 

más sobre las diferencias entre el mango y el ID del hilo se puede encontrar here.

Editar

Parece @himself corregir su error después de ver mi respuesta, por lo que este ya no es relevante.

+0

@kobik sí y lo hice en el pasado, pero mira cómo funciona esta comunidad: mucha gente dio +1 sin verificar realmente si la respuesta de sí mismo es correcta. – Wodzu