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 call Terminate
, 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 Assigned
is if you're expecting the Thread1
variable to be nil
. Do you ever assign Thread1 := 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 set FreeOnTerminate
, then it's incorrect to check the Finished
property, too, because it might have already finished and freed itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With