You can create an event (for example, ManualResetEvent ) in each thread and save it in a synchronized list (using the lock construct). Set an event or remove it from the list when the task is completed.
If you want to join, you can use WaitHandle.WaitAll ( MSDN documentation ) to wait for all events to be signaled.
It’s a hack, but I don’t see how to reduce it to something simpler!
Edit: In addition, you can guarantee that new events will not be published, and then wait a couple of seconds. If they are really short-lived, you will not have a problem. Even simpler, but more hacks.
Finally, if this is just a short period of time, the service will not exit until all threads die (if they are not background threads); therefore, if this is a short period of time, the service control manager will not mind for a second or so - you can just leave them on time - in my experience.
source share