The item #4 is an invitation for a failure.
For a high-availability service, unpredictable number of threads is a big no-no. Besides, you already spawn a separate thread for some clean-up, why also a timer. A timer is even worse than thread in terms of reliability. Did you ever try to handle the situations where a timer event if fired when a handle triggered by a previous event is still running? This is solvable, but hardly worth the effort.
By the way, if you need to poll a database periodically or something, I have an improved schema combining timer and thread, where the timer merely sets the shared
EventWaitHandle
. Please see my past solution:
Polling Database with Timer[
^].
This post also illustrates perhaps the best approach to threads on a server: you create just on thread "per-purpose" in the very beginning of the run time and throttle it with some thread synchronization object (in this case, in instance of
EventWaitHandle
) to keep it sleeping until there is a task for it.
In this way, the number of threads during run-time is not changed. The number of threads is either fixed or defined by configuration data and is kept fixed after the threads are created in the very beginning. Remember that the creation of a thread is also pretty expensive.
Another approach based on this idea is the blocking queue used to inter-thread communicate. Please see my Tips & Tricks article:
Simple Blocking Queue for Thread Communication and Inter-thread Invocation[
^].
—SA