2010-10-28 16 views
20

In delphi, un metodo in TThread è terminato. Sembra che un sottotitolo non possa uccidere un altro thread chiamando terminato o libero. Ad esempio A (forma principale), B (un'unità di filettatura), C (un'altra forma).Come uccidere un thread in delphi?

B sta inviando dati al modulo principale e C (chiamando syncronize), abbiamo provato a terminare B in C mentre B è in esecuzione chiamando B.terminate. Ma questo metodo non funziona e B funziona ancora fino a quando non termina con il metodo di esecuzione.

prega di aiuto. Grazie in anticipo.

risposta

41

È necessario verificare la presenza di una terminazione nella filettatura affinché funzioni. Per esempio:

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 questo, è possibile chiamare

MyThread.Terminate; 

e si metterà a terminare non appena termina l'elaborazione di un altro pezzo di lavoro. Si chiama "graceful termination thread" perché al thread stesso viene data la possibilità di terminare qualsiasi lavoro e prepararsi per il termine.

C'è un altro metodo, chiamato "terminazione forzata". È possibile chiamare:

TerminateThread(MyThread.Handle); 

Quando si esegue questa operazione, Windows interrompe in modo forzato qualsiasi attività nel thread. Questo non richiede il controllo di "Terminato" nel thread, ma potenzialmente può essere estremamente pericoloso, perché stai uccidendo thread nel bel mezzo dell'operazione. Dopo di ciò, la tua applicazione potrebbe bloccarsi.

Ecco perché non si utilizza mai TerminateThread finché non si è assolutamente sicuri di avere tutte le possibili conseguenze accertate. Al momento non lo fai, quindi usa il primo metodo.

+1

Grazie Timo. Risposta chiara ed esempi. – Dylan

+0

E grazie anche a te stesso. un ottimo esempio. – Dylan

+3

Non solo l'applicazione potrebbe bloccarsi, ma anche le risorse utilizzate dal thead non verranno deallocate. TerminateThread() è una chiamata "extrema ratio". –

12

Terminare non uccide un thread; imposta la proprietà Terminated per informare il thread che deve terminare. È responsabilità del thread guardare per Terminated e chiudersi con grazia.

3

Tutto il metodo Terminate imposta la proprietà Terminated su true. Quindi devi continuare a controllare manualmente quella proprietà e quindi uscire dal metodo thread quando è impostato su true.

0

Se si desidera terminare una discussione, è possibile che si stia meglio creando un'altra app e uccidendola se si ritiene che non sia riuscita, Windows si riordina dopo di te.

14

In realtà,

attualmente la maggior parte ha votato risposta a questa domanda non è corretta (così come 34 upvoters ...) per quanto riguarda il modo di uccidere con forza un filo.

È non utilizzare ThreadId come parametro per la procedura TerminateThread. L'utilizzo di ThreadId causerà molto probabilmente un errore "Handle non valido" o, nel peggiore dei casi, scenerio - ucciderà un thread diverso.

Si dovrebbe passare un thread handle come parametro:

TerminateThread(MyThread.Handle); 

più su differenze tra la maniglia del thread e id può essere trovato here.

Modifica

Sembra @himself correggere il suo errore dopo aver visto la mia risposta, quindi questo non è più rilevante.

+0

@kobik sì e l'ho fatto in passato, ma guarda come funziona questa comunità: molte persone hanno dato +1 senza verificare realmente se la risposta di lui fosse corretta. – Wodzu

Problemi correlati