Hi all,
I've worked with threads a lot, but I'm stumped by how to do what seems to be a normal setup.
I have a service application that launches a new thread (TCopyThread) that copies a file using TFileStream objects. The main service thread only calls a TTimer object every so often to create another TCopyThread when the last one has finished. (Down the track I'll work on allowing more than one TCopyThread run, plus there could be more different types of threads.) The thread can be terminated in response to
[ul]
[li]the service being stopped[/li]
[li]the service thread deciding using it's own logic that the thread should be terminated[/li]
[li]the TCopyThread finishing it's copy process[/li]
[/ul]
At the moment I have an event attached to TCopyThread.OnTerminate that runs cleanup code and provides feedback on how far the thread went with the copy operation.
That seems to work for everything except when the service is stopped. I have code similar to
Except it hangs where indicated. I'm pretty sure this is because the event I've attached to TCopyThread.OnTerminate is called using Synchronize internally by the TThread object, meaning that it doesn't get called because the main service thread is stuck waiting for the thread to finish. That doesn't make much sense to me, so perhaps I'm misunderstanding why it's not working.
I've tried using messages and having the thread post a message to the service thread handle (ServiceThread.Handle) when it's finished and without attaching anything to the OnTerminate event. The message method in the service thread then does the cleanup. In the ServiceStop method I used [tt]WaitMessage[/tt] instead of [tt]WaitFor[/tt] thinking it would wait until the message was received from TCopyThread, but it never processed it.
What's the go on getting this to work?
I've worked with threads a lot, but I'm stumped by how to do what seems to be a normal setup.
I have a service application that launches a new thread (TCopyThread) that copies a file using TFileStream objects. The main service thread only calls a TTimer object every so often to create another TCopyThread when the last one has finished. (Down the track I'll work on allowing more than one TCopyThread run, plus there could be more different types of threads.) The thread can be terminated in response to
[ul]
[li]the service being stopped[/li]
[li]the service thread deciding using it's own logic that the thread should be terminated[/li]
[li]the TCopyThread finishing it's copy process[/li]
[/ul]
At the moment I have an event attached to TCopyThread.OnTerminate that runs cleanup code and provides feedback on how far the thread went with the copy operation.
That seems to work for everything except when the service is stopped. I have code similar to
Code:
[b]procedure[/b] TCopyBak2.ServiceStop(Sender: TService; [b]var[/b] Stopped: Boolean);
[b]begin[/b]
[b]if[/b] Assigned(FCopyThread) [b]then[/b]
[b]begin[/b]
FCopyThread.Terminate;
FCopyThread.WaitFor; [navy][i]// this hangs the service
[/i][/navy] [b]end[/b];
[navy][i]// snip
[/i][/navy] Stopped := True;
[b]end[/b];
Except it hangs where indicated. I'm pretty sure this is because the event I've attached to TCopyThread.OnTerminate is called using Synchronize internally by the TThread object, meaning that it doesn't get called because the main service thread is stuck waiting for the thread to finish. That doesn't make much sense to me, so perhaps I'm misunderstanding why it's not working.
I've tried using messages and having the thread post a message to the service thread handle (ServiceThread.Handle) when it's finished and without attaching anything to the OnTerminate event. The message method in the service thread then does the cleanup. In the ServiceStop method I used [tt]WaitMessage[/tt] instead of [tt]WaitFor[/tt] thinking it would wait until the message was received from TCopyThread, but it never processed it.
What's the go on getting this to work?