Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: WaitFor() thows 'Invalid handle' error?


This question is answered.


Permlink Replies: 6 - Last Post: Dec 21, 2016 10:35 AM Last Post By: Remy Lebeau (Te... Threads: [ Previous | Next ]
Toby Dobbs

Posts: 77
Registered: 9/24/16
WaitFor() thows 'Invalid handle' error?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 20, 2016 5:12 AM
I have a thread which runs until certain criterion including the beginning of another thread. By the time the new thread starts I want to be certain that the other thread has absolutely terminated. To do this I tried using WaitFor() but an 'invalid handle' error is consistently thrown. I have seen this reported but I couldn't find a well-documented solution. Any help would be appreciated.
Alex Belo

Posts: 626
Registered: 10/8/06
Re: WaitFor() thows 'Invalid handle' error?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 20, 2016 7:36 AM   in response to: Toby Dobbs in response to: Toby Dobbs
Toby Dobbs wrote:

I tried using WaitFor() but an 'invalid handle' error is
consistently thrown.

Show your actual code.

--
Alex
Toby Dobbs

Posts: 77
Registered: 9/24/16
Re: WaitFor() thows 'Invalid handle' error?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 20, 2016 7:46 AM   in response to: Alex Belo in response to: Alex Belo
if TCheckBox(Sender).Checked then
begin
  if thread2.Terminated then thread2 := TPlotThread.Create(True);
  thread2.Start;
end
else
begin
  thread2.Terminate;
  // thread2.WaitFor;
end;


This is the procedure for terminating (which includes freeing) or starting a new thread - based on whether the checkbox is checked or not. Terminated is a property I set when teminating the thread - it's just a boolean flag.

Edited by: Toby Dobbs on Dec 20, 2016 7:46 AM
Alex Belo

Posts: 626
Registered: 10/8/06
Re: WaitFor() thows 'Invalid handle' error? [Edit]
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 20, 2016 7:58 AM   in response to: Toby Dobbs in response to: Toby Dobbs
Toby Dobbs wrote:

if TCheckBox(Sender).Checked then
begin
if thread2.Terminated then thread2 := TPlotThread.Create(True);
thread2.Start;
end
else
begin
thread2.Terminate;

I suspect that thread2->FreeOnTerminate is true.

In this case thread2 can finish and free itself BEFORE next statement

// thread2.WaitFor;
end;

and thread2 is not exists at this moment.

--
Alex
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: WaitFor() thows 'Invalid handle' error? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2016 10:22 AM   in response to: Alex Belo in response to: Alex Belo
Alex wrote:

I suspect that thread2->FreeOnTerminate is true.

Agreed.

In this case thread2 can finish and free itself BEFORE next statement

Or even WHILE Waitfor() is still running.

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: WaitFor() thows 'Invalid handle' error? [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2016 10:35 AM   in response to: Toby Dobbs in response to: Toby Dobbs
Toby wrote:

if thread2.Terminated then thread2 := TPlotThread.Create(True);

That statement is a memory leak, unless you use FreeOnTerminate=true. However,
if you do use FreeOnTerminate=true then you can't use WaitFor(). They cannot
be used together.

Also, you cannot call Start() on a thread that has already been started.

Try something more like this:

procedure TMyForm.CheckBoxClick(Sender: TObject);
begin
  if TCheckBox(Sender).Checked then
  begin
    if (thread2 <> nil) and thread2.Terminated then
    begin
      thread2.WaitFor;
      FreeAndNil(thread2);
    end;
    if thread2 = nil then
      thread2 := TPlotThread.Create(False); // FreeOnTerminate=False
  end
  else if thread2 <> nil then
  begin
    thread2.Terminate;
    thread2.WaitFor;
    FreeAndNil(thread2);
  end;
end;


If you want to use FreeOnTerminate=true, then try something more like this:

procedure TMyForm.CheckBoxClick(Sender: TObject);
begin
  if TCheckBox(Sender).Checked then
  begin
    if (thread2 <> nil) and thread2.Terminated then
    begin
      repeat
        CheckSynchronize;
        Sleep(10);
      until thread2 = nil;
    end;
    if thread2 = nil then
    begin
      thread2 := TPlotThread.Create(True); // FreeOnTerminate=True
      thread2.OnTerminate := ThreadTermianted;
      thread2.Start;
    end;
  end
  else if thread2 <> nil then
  begin
    thread2.Terminate;
    repeat
      CheckSynchronize;
      Sleep(10);
    until thread2 = nil;
  end;
end;
 
procedure TMyForm.ThreadTerminated(Sender: TObject);
begin
  thread2 = nil;
end;


--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: WaitFor() thows 'Invalid handle' error?  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2016 10:23 AM   in response to: Toby Dobbs in response to: Toby Dobbs
Toby wrote:

To do this I tried using WaitFor() but an 'invalid handle' error is
consistently thrown.

Are you using FreeOnTerminate=true? You can't use that with WaitFor().

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02