How can I properly stop a thread when an application is closing?
I do this:
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if not Thread1.Finished
then
begin
Thread1.Terminate;
Thread1.WaitFor();
end;
end;
But on Thread1.WaitFor I have an error: “Thread Error: The handle is invalid (6).” If I do WaitForSingleObject(Thread1.Handle,infinite) instead of WaitFor all is ok.
Why if I use Thread.freeonterminate := false then WaitFor works good? Explain me please what I do wrong.
As I understand I need to use “if Assigned” instead of “if not Thread1.Finished”, right?
When you set
FreeOnTerminate = True, the thread object automatically frees itself when it terminates. So, after it terminates, any further calls on that object are invalid. As soon as you callTerminate, you have to assume that the object no longer exists.If you need to do further operations on a thread after starting it, then don’t set
FreeOnTerminate. Instead, free it manually after you’re really finished using it.The only time you would use
Assignedis if you’re expecting theThread1variable to benil. Do you ever assignThread1 := nil? If not, then you shouldn’t expect it to have that value. As you should know, variables don’t suddenly change their values when you call methods on them. But if you’ve setFreeOnTerminate, then it’s incorrect to check theFinishedproperty, too, because it might have already finished and freed itself.