I'm having a little trouble shutting down a thread that might or might not be executing when the program closes. The thread, actually there are two of them, is started in an OnTimer event, and in OnDestroy I stop the timers then I want to close the threads.

The thread code itself is pretty simple and this is what I have now.

Still, I get an access violation error, and when I use the WaitFor function I get lots of odd errors, such as invalid handle.

// Constructor
constructor TDaqThread.Create(OnTerminate:TNotifyEvent);
begin
  inherited Create(true);
  Self.OnTerminate:=OnTerminate;        // Defines the onTerminate event handler
  FreeOnTerminate:=true;                // Thread frees itself when it terminates
  Resume;                               // Start the thread
end;

// The thread executes a single procedure
procedure TDaqThread.Execute;
begin
  try
    MainForm.DoUpdateDaq;
  except
    on E:Exception do
    begin
     // Handle the error.
    end
  end;
end;

// Here is how I create/start the thread.  When it is done I run the 
// EndUpdateDaq procedure.

        DaqThread:=TDaqThread.Create(EndUpdateDaq)

// At the beginning of the EndUpdateDaq procedure...
procedure TMainForm.EndUpdateDaq(Sender:TObject);
begin
  try
    // Has the Daq thread been terminated?
    if DaqThread<>nil then
     if DaqThread.Terminated then
       Exit;

// More stuff...

end;

Procedure TMainForm.OnDestroy(Sender:TObject);
begin
  MonitorTimer.Enabled:=false;

  if DaqThread <> nil then
    if not DaqThread.Terminated then
    begin
      DaqThread.OnTerminate:=nil;
      DaqThread.Terminate;       // Stop the Daq thread
  //    DaqThread.WaitFor;         // Wait for it to terminate
    end;

// more stuff...
end;

I think I may have figured it out.

First, it turns out that if you set to thread to automatically free itself when it is done that you shouldn't ever mess with it again. Just fire and forget.

Instead of shutting it down I just enter a loop that waits for it to finish, then I move on to the next task. Of course the loop has a timeout.

To check if the thread is done I don't check directly with the thread because you never know when it will disappear, but rather I check a variable I set just before starting the thread and clear when it finishes it's onTerminate procedure.

I hope this helps.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.