No, il codice non è buono (anche se probabilmente funzionerà in 99,99% o addirittura il 100% dei casi). Se hai intenzione di terminare il thread di lavoro dal thread principale, non impostare FreeOnTerminate su True (non vedo cosa stai cercando di ottenere nel codice precedente impostando FreeOnTerminate su True, almeno rende il tuo codice meno comprensibile) .
Una situazione più importante con la terminazione dei thread di lavoro è che si sta tentando di chiudere un'applicazione mentre il thread di lavoro è in stato di attesa. Il thread non si risveglierà se si chiama Terminate, in genere si dovrebbe utilizzare un ulteriore oggetto syncronization (solitamente un evento) per riattivare il thread di lavoro.
E ancora un'osservazione - non v'è alcuna necessità di
begin
MyThread.Terminate;
MyThread.WaitFor;
MyThread.Free;
end;
se si guarda al codice TThread.Destroy, chiama Terminate and WaitFor, così
MyThread.Free;
è sufficiente (almeno in Delphi 2009, non ho a disposizione fonti di Delphi 7 per verificare).
Aggiornato
Leggi mghie risposta. Si consideri la seguente situazione (meglio su 1 sistema della CPU):
thread principale sta eseguendo
procedure TMainForm.Close;
begin
if not MyThreadReady then
begin
MyThread.Terminate;
MyThread.WaitFor;
MyThread.Free;
end;
end;
farlo controllare valore MyThreadReady (è False) ed è stato spento dal scheduler.
Ora lo scheduler passa al thread di lavoro; esegue
Synchronize(ThreadFinished);
e impone lo scheduler per tornare al thread principale. Filo principale continua esecuzione:
MyThread.Terminate; // no problem
MyThread.WaitFor; // ???
MyThread.Free;
puoi dire cosa succederà a WaitFor? Non posso (richiede una visione più approfondita delle fonti di TThread per rispondere, ma a prima vista sembra una situazione di stallo).
Il tuo errore reale è qualcosa di diverso - hai scritto un codice inaffidabile e stai cercando di scoprire se è corretto o meno. Questa è una cattiva pratica con i thread: dovresti imparare a scrivere un codice affidabile.
Come per le risorse: quando TThread (con FreeOnTerminate = False) viene terminato, le sole risorse che rimangono allocate sono l'handle di thread di Windows (non utilizza risorse di Windows sostanziali dopo che il thread è terminato) e l'oggetto Delphi TThread in memoria. Non è un grosso costo essere dalla parte della sicurezza.
Ciao! FreeOnTerminate da solo non è un'opzione. D'altra parte non voglio che il thread esegua la memoria durante l'esecuzione del programma principale. Sto sincronizzando il booleano perché credo che garantisca che verrà eseguito prima di MainForm.Close o dopo MainForm.Close. Quindi MyThread.Terminate verrà chiamato solo se FreeOnTerminate è falso. Sto sbagliando qui? – Steve
Quanta memoria ha il thread 'hog' una volta finito? Se non puoi dire di non avere motivo di preoccuparti. Misura prima. Ma se insisti, quindi pubblica un messaggio dal tuo thread come ultima cosa e libera il thread nel gestore del messaggio. 'Synchronize()' è troppo vile anche solo per pensare se il tuo codice funzionerebbe in tutte le circostanze. Dì solo di no. – mghie
Accettare questa soluzione come la più pulita. Grazie a tutti per le risposte! – Steve