2010-09-24 13 views
5

Hello Nel mio modulo creo TFrame in fase di runtime. In questo frame creo thread in background con i comandi execute in loop infinito. Ma quando distruggo questo frame dovrei distruggere questo thread. provoCorretto il thread destroy

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

ma ottengo AV e ThreadError. Come posso distruggere il thread?

+0

possibile duplicato di [Libera un TThread modo automatico o manuale] (http://stackoverflow.com/questions/3557105/free-a-tthread-either-automatically-or-manually) –

+3

Non sospendere il filo. Il metodo terminate imposta semplicemente la proprietà Terminated su true e il metodo Execute è responsabile della chiusura del thread. Se è sospeso, non avrà la possibilità di terminare. – jachguate

+0

Un altro problema con il codice sopra, è che probabilmente libera la discussione prima che abbia una modifica per terminare il modo normale. –

risposta

13

È necessario assicurarsi che esce filo è metodo execute per terminare in modo corretto.

codice potrebbe essere qualcosa di simile:

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

chiamata quando si desidera distruggere discussione:

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

Non è necessario chiamare 'Terminate' e' WaitFor' dall'esterno, poiché il distruttore di thread lo farà da solo. Potrebbe essere necessario però richiamarlo dai distruttori sovrascritti, prima che tutti i campi vengano liberati, per assicurarsi che questi non vengano più utilizzati dal thread. – mghie

4

E 'sufficiente fare thread.Terminate. Ma probabilmente vorrai impostare thread.FreeOnTerminate := true quando viene creato.

Ovviamente, nel circuito chiuso del thread (ovvero, in Execute), è necessario verificare se il thread è stato richiesto di terminare (controllare la proprietà Terminated). Se si scopre che il thread è stato richiesto di terminare, è sufficiente interrompere il ciclo e uscire da Execute.

+0

thread.Terminate solo imposta la proprietà FTerminated su True. Non distrugge il filo. – Linas

+2

Lo so. Ma ogni thread deve verificarlo nel suo metodo Execute.Presumo che l'OP stia facendo questo. –

4

Non si dovrebbe mai chiamare sospendere su un TThread la sua non è sicuro di farlo e curriculum dovrebbe essere utilizzato solo per avviare un thread che è stato creato sospeso.

In Delphi 2010, la sospensione e riprendere da dove ammortizzati e che il metodo start è stato introdotto per rafforzare questa.

Per una spiegazione più completa vedono questo thread al forum Codegears.

aver detto che ci sono 2 modi che verrà interrotta e liberare un TThread.

1: Mi è FreeOnTerminate quando viene creato il filo in modo mi basta chiamare.

Thread.Terminate; 

2: liberare il filo in modo esplicito, come ho bisogno di leggere il risultato da una proprietà pubblica prima che il thread viene liberato e dopo che è terminato.

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

Nella principale eseguire ciclo può essere una buona idea di mettere un po 'la gestione delle eccezioni in. Oppure si può essere lasciato chiedendo perché il filo sembra porre fine alla sua auto. Ciò potrebbe causare l'AV se il thread è impostato su FreeOnTerminate ed è già stato liberato quando si tenta di liberarlo.

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