Resolved Detecting the end of a thread

cbreemer

Well-known member
Joined
Dec 1, 2021
Messages
184
Programming Experience
10+
I am struggling with something that I feel should be simple... once you know how.
I have a Windows Form that implements a rudimentary print queue monitor. It starts a thread which goes into an endless loop, each second checking the local printer queue and calling Invoke(new MethodInvoker(delegate ()... to update the UI. It works beautifully, but now my extra requirement is that as soon the number of jobs reaches zero, the form terminates itself. A fairly normal thing to want, I would hope ?

Trying to close the form from within the delegate function in the thread body does not seem like a good idea. No matter what I try, this hangs the application.
I guess it would have to be the main thread terminating the form. But how does the main thread know that the worker thread has ended ? I don't want to be polling the thread's isAlive flag as that would make the form unresponsive. I read about Thread.Abort() being unreliable, and I would not know how the main thread could catch the ThreadAbortException anyway. Is there some event that the thread can raise which then calls an event handler in the form ? I googled around but the dozens of different ideas and suggestions only serve to confound me 😯 I hope someone here has been there and done that.
 
Solution
On your UI thread, create a Windows timer that fires every second or so. In the handler far that timer, use Thread.Join(int) passing in a small delay -- perhaps just 100 milliseconds. Check the return value. If the return value is true, then the thread has terminated and you can call Form.Close().
So are you saying that a worker thread is totally useless when you need to update the UI from the background ? Perhaps in hindsight, a timer would have been a better choice, but that idea didn't occur to me when I started. I might still try it, anything that uncomplicates things is welcome. OTOH, it looks like it's working fine now, so why change it...
If all the background thread does is invoke a method on the UI thread then yes, the background thread is useless. If your background thread sleeps for a second and then invokes a method on the UI thread then that's basically equivalent to having a Timer with an Interval of 1 second and no background thread. If you use a Timer and then execute code in the Tick event handler, the UI thread will only be busy while that Tick event handler is executing, but the UI thread would be busy for the same period of time if the same code was executed in a method invoked on the UI thread from a background thread.
 
Thanks again guys. There are so many different approaches now that I'm spoilt for choice. Not being a lover of abstraction (unless it really makes things simpler) I think I'll change to using a Timer now, as it's the simplest solution, and use my newly gained BackgroundWorker expertise on another project where it seems more appropriate.
 
Something to keep in mind is that the Interval of the Timer will be the period between the start of each pair of process, not the period between the end of one and the start of the next. If you want the former then you're good to go but if you want the latter then you'll need to Stop the Timer at the top of the Tick event handler and then Start it at the bottom.
 
Something to keep in mind is that the Interval of the Timer will be the period between the start of each pair of process, not the period between the end of one and the start of the next. If you want the former then you're good to go but if you want the latter then you'll need to Stop the Timer at the top of the Tick event handler and then Start it at the bottom.
Yes, that makes sense now that you mention it. Luckily in my case the exact interval is not at all important. As long as it updates the UI every one or two seconds.
 
Back
Top Bottom