Strange problem in threads, application doesn't exit
OK I'm writing a Zoom component and I wanted it to capture from screen within a secondary thread.
You can pretend I just want to derive TThread in an empty component. I didn't write any codes in the thread so it is just a simple useless thread. I wrote this code: Thrd := TCaptureThread.Create(False);
in the component main class.
Then I wrote Thrd.Free
in the main class destruction code. Now when I close the whole application, although it destroys everything, the process doesn't terminate completely. In Windows Task Manager shows that number of threads is 1 but the process remains. If I comment the thread creation line, everything becomes OK and application terminates quickly. What am I开发者_如何学Python gonna do about this? :(
Thanks in advance
When you call Thrd.Free
the following code from TThread.Destroy
is run:
Terminate;
if FCreateSuspended then
Resume;
WaitFor;
Calling Free
on a thread will thus terminate the thread synchronously.
My guess is that the call to WaitFor
never returns. Perhaps TCaptureThread.Execute
doesn't check Terminated
and exit. Perhaps TCaptureThread
is waiting on the main thread and so the wait on the thread deadlocks.
It's pretty hard to do anything other than guess, based on your question, but I'd want to check whether or not your code gets past the WaitFor
call in the destruction of Thrd
. Enable Debug DCUs, set a breakpoint one the call to WaitFor
and see for yourself.
That can be SO many thing... From the Execute
method of your thread never exiting to a deadlock.
First thing you should do to try to diagnose is run your application under Delphi. Then, since you say it's at the closing of the application it hangs, you close the application. Now that your application hanged, you pause the application and check the Thread debug panel. There, click on each thread to check their callstack. That should give a better idea of why it hangs, and exactly which thread hangs.
Write your thread on this way:
type
TCaptureThread = class(TThread)
private
//
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: False);
end;
implementation
constructor TCaptureThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
// Set FreeOnTerminate to True
FreeOnTerminate := True;
end;
procedure TCaptureThread.Execute;
begin
// Write the Execute method here...
// And don't forget to synchronise with the form
end;
end.
In the form, instantiate your thread
Thrd := TCaptureThread.Create(False);
Execute it
Thrd.Execute;
And terminate your thread
Thrd.Terminate;
I've been using threads on this way for a while, and I never had problems.
精彩评论