I came accross a mail thread which deals with the problem i was facing some time back. Sharing it to you all.
I have written a windows service in .Net that uses the ThreadPool.QueueUserWorkItem() call to do some processing. Each work item to the thread pool takes the same type of object to process (although with different arguments). At any given time, there will be a max of 8 items that I would have added to the thread pool. Each thread would take approx < 1 min to finish the processing.
Is there any way for the Service.OnStop() method to know which threads in the threadpool are running processes started by the main thread and is there any way to graciously stop those threads so that the system remains in a clean state when the service is stopped?
I’m not sure if this is the correct way, but the way I do it is the following:
Create a bool that your worker threads check to determine whether they should return immediately (e.g. public bool Shutdown_Now = false). Then in your OnStop() do: Shutdown_Now=true; Now you might want to assume that your threads have quit, but in the event that they haven’t, your service will fail to stop (which is probably a bug). Generally to prevent this from ever occurring, I’ll store a reference to Thread.CurrentThread whenever a worker thread starts. Then when OnStop() is called, I’ll notify them to quit with the Shutdown_Now bool and wait to see if the threads are still running after N seconds. If they are, then I’ll call thread.Abort().
So long as you keep track of all the worker threads being used and make sure you dereference the threads that have completed, you shouldn’t have a problem
What I have done and don't know if this is the best way is to create a ManualResetEvent and pass it to my worker threads. My worker threads will keep checking this and if it gets signaled they will shutdown. My OnStop() method simply signals the ManualResetEvent. I also create ManualResetEvents that my worker threads signal when they finish and I can also listen for those after I ask them to shutdown.
We had a similar problem. Have some global object that all threads can access. In your OnStop set that signal variable so that all threads would know that on stop is signaled. You will have to implement a logic in each thread function to check the stop signal variable and wind up processing immediately. Also once you set the variable in OnStop, put a sleep for 10-15 seconds (based on how much is your winding logic for each thread).
All these solution are pretty similar in the sense the onus (and logic) was on the worker thread to keep checking at regular interval if it has to stop processing. which i don't like doing. this makes me wish there was a way i could signal to a worker thread to exit as fast as it can but this is not supported as of now :(.