This is probably the worst possibly design for getting some periodic on near-periodic behavior of a thread. There are many reasons for that, no need to discuss them all. The cost of creation of a new thread instance and starting it is one of the factors, but, by far, not the worst. The worst thing is the easy possibility to mess up everything.
Much better straightforward solution would be creation of only one additional thread and keeping it executing during pretty much all of the application lifetime. You simply make it executing in an "infinite" loop (in fact, broken only when the application is about to close) and throttle its activity by using an event wait handle object.
It's important to understand that on the call
WaitHandle.WaitOne
the thread either passes or is put to a special
wait state; it is switched off and never scheduled back to execution until it is waken up, which happens on
Thread.Abort
,
Thread.Interrupt
, timeout, and other events, in particular, signalling the wait handle object from another thread. This way, the thread spends zero CPU time in wait state, there is no spin wait, not periodic checks of the state, nothing.
Please see:
EventWaitHandle Class (System.Threading)[
^].
Please see my past answers:
Making Code Thread Safe[
^],
pause running thread[
^],
ManualResetEvent and AutoResetEvent in Thread[
^],
Running exactly one job/thread/process in webservice that will never get terminated (asp.net)[
^].
Pay special attention for the alternative related technique of using a blocking collection; it is unrelated to your immediate question but important to understand.
Now, let's come back to "periodic" repetition by timer. I'm not sure you need it this way. One alternative would be just repeating the piece of code in a thread on its own, taking current real time from, say,
System.DateTime.Now
, calculation of next execution time and calling
Thread.Sleep
with appropriate duration. But if you really need a timer (again, I don't know why), its only function would be signaling event wait handle by calling
EventWaitHandle.Set()
, which wakes up the thread waiting on this event handle instance. Note that this call is thread-safe, unlike almost any other call of some methods. Also note that the timer event happens in some thread you don't know (except really bad
System.Windows.Forms.Timer
which invokes the tick handler in the UI thread, but this "relief" it its only benefit; in most cases, it should never be used, as the timing is devastatingly bad).
Both techniques solves the biggest problem you may face. What could happen if you start some processing if the processing caused by your previous timer tick is not yet complete? It can be hard to imagine all the possible mess. The solutions I suggest are completely free from this problem.
—SA