Don't use a timer to spawn threads. Only ever start one thread. When the thread has finished a work cycle, calculate how long remains before the next cycle should start. If this interval is 0 or negative, loop back immediately and start a new cycle, if positive, sleep for that interval before looping back.
This is usually done by taking the int result of an unsigned int subtraction between the finish ticks and start ticks, so giving the elapsed ticks taken by the work. Subtracting this from the desired interval gives the new time remaining.
No extra timer thread needed, no possibility of two threads running simultaneously, simplified overall design, no continual create/start/terminate/destroy, no mallocs, no new(), no stack allocate/deallocate, no GC.
Other designs using timers, mutexes, semaphores, locks etc. are just over complex. Why bother trying to stop the extra threads with synchro if it's just plain easier and simpler to not make any extra threads?
Sometimes, using a timer instead of a sleep() loop is just a really bad idea. This sounds like one of those times.
public void doWorkEvery(int interval)
{
while (true)
{
uint startTicks;
int workTicks, remainingTicks;
startTicks = (uint)Environment.TickCount;
DoSomeWork();
workTicks=(int)((uint)Environment.TickCount-startTicks);
remainingTicks = interval - workTicks;
if (remainingTicks>0) Thread.Sleep(remainingTicks);
}
}