As you are probably already aware, there are 3 different timer classes
available within the .NET framework.
- System.Timers.Timer
- System.Threading.Timer
- System.Windows.Forms.Timer
I was thinking about the applicability of each timer so I could decide which
one to use within my application and I could not clearly remember the
differences between System.Timers.Timer and System.Threading.Timer. Thankfully
there is a great
MSDN article that deals with exactly this subject. It's worth a read even
though you might think you know all the differences. It will also remind you of
the event re-entry issue that is often overlooked until a bug report ends up on
your hands.
[Update]
I thought I'd be a bit more useful and provide a summary of the article here
rather than force you to read the whole thing.
System.Windows.Forms.Timer
- The
elapsed event is fired on the UI thread so there is no need for
synchronization code
- Not
accurate due to its dependency on the UI thread
- If the
UI thread is not available to process the timer's request, the elapsed
event will not be fired (e.g.
calling Thread.Sleep on the UI thread for a period of time longer than the
timer interval will result in at least one timer event to not be fired)
- No
issues with event handler re-entry as everything is executing in one
thread
System.Timers.Timer
- Ideal
for multi-threaded server applications as it is thread-safe and can be
manipulated by multiple threads
- The
elapsed event is typically executed using a .NET ThreadPool thread.
- Can be
synchronized with UI controls so that the elapsed event is fired on the
thread that created the controls, but if the UI thread is not available
for processing the timer's request, the event will be fired when the
thread because available again.
- Event
handler re-entry has to be catered for by temporarily suspending the
timer.
System.Threading.Timer
- It is
not thread-safe and access through multiple threads has to make use of
custom synchronization logic (e.g. lock() {})
- The
elapsed event is typically executed using a .NET ThreadPool thread.
- Cannot
be synchronized with UI controls so that the elapsed event is fired on the
thread that created the controls. Such synchronization has to be achieved
manually using the methods Control.Invoke and Control.BeginInvoke.
- Event
handler re-entry has to be catered for by temporarily suspending the
timer.