2010-09-24 8 views
5

Hola En mi formulario, creo TFrame en tiempo de ejecución. En este marco, creo hilo de fondo con ejecuta comandos en bucle sin fin. Pero cuando destruya este marco, debería destruir este hilo. TratoCorregir el hilo destruir

thread.Suspend; 
thread.Terminate; 
FreeAndNil(thread); 

pero consigo AV y ThreadError. ¿Cómo debo destruir el hilo?

+0

posible duplicado de [libere a un TThread forma automática o manual] (http://stackoverflow.com/questions/3557105/free-a-tthread-either-automatically-or-manually) –

+3

No suspender la amenaza. El método de terminación simplemente establece la propiedad Terminated en verdadero, y su método Execute es responsable de terminar el hilo. Si se suspende, no tendrá la oportunidad de terminar. – jachguate

+0

Otro problema con el código anterior es que probablemente libera el hilo antes de que tenga un cambio para terminar de la manera normal. –

Respuesta

13

Debe asegurarse de que el hilo sale de su método de ejecución para terminarlo correctamente.

Código podría ser algo como esto:

procedure TThread.Execute; 
begin 
    while not Self.Terminated do 
    begin 
    //do something 
    end; 
end; 

llamada cuando quiere destruir hilo:

thread.Terminate; 
thread.WaitFor; 
FreeAndNil(thread); 
+0

No es necesario llamar 'Terminate' y' WaitFor' desde el exterior, ya que el thread destructor lo hará por sí mismo. Sin embargo, puede ser necesario llamarlo desde destructores sobrescritos, antes de que se liberen los campos, para asegurarse de que ya no se utilicen desde el hilo. – mghie

4

Es suficiente hacer thread.Terminate. Pero es probable que desee establecer thread.FreeOnTerminate := true cuando se crea.

Por supuesto, en el lazo apretado de su hilo (es decir, en Execute), necesita comprobar si se ha solicitado la terminación del hilo (consulte la propiedad Terminated). Si encuentra que el subproceso se ha solicitado que termine, simplemente salga del ciclo y salga de Execute.

+0

thread.Terminate solo establece la propiedad FTerminated en True. No destruye el hilo. – Linas

+2

Lo sé. Pero cada hilo debe verificar eso en su método Execute.Supongo que el OP está haciendo esto. –

4

Nunca se debe llamar a suspender en un TThread no es seguro hacerlo y curriculum vitae solo debe usarse para iniciar un hilo que se haya creado suspendido.

En Delphi 2010 se suspendieron y reanudaron donde se depreciaron y se introdujo el método para reforzar esto.

Para una explicación más completa, consulte este thread en los foros de Codegears.

habiendo dicho que hay 2 formas en que terminaré y liberaré un tthread.

1: Configuro FreeOnTerminate cuando se crea el hilo, así que solo llamo.

Thread.Terminate; 

2: Liberar el hilo de forma explícita, ya que necesito para leer el resultado de una propiedad pública antes de que se liberó el hilo y después de que haya terminado.

Thread.Terminate; 
Thread.WaitFor; 
//Do somthing like read a public property from thread object 
if Thread <> nil then FreeAndNil(Thread); 

En general ejecutar bucle puede ser una buena idea para poner un poco de manejo de excepciones en. O quizás se pregunte por qué el hilo parece poner fin a su auto. Esto puede estar causando el AV si el subproceso está configurado en FreeOnTerminate y ya se ha liberado cuando intenta liberarlo.

procedure TThread.Execute; 
begin 
    while not Terminated do 
    begin 
    try 
     //do something 
    except 
     on E:Exception do 
     //handle the exception 
    end; 
    end; 
end; 
Cuestiones relacionadas