1

Is there any difference between

System.Threading.Timer

System.Threading.Timer timer = new System.Threading.Timer(new TimerCallback(PerformAction), null, 0, 15000);

and

using a System.Timers.Timer inside a new thread?

Thread thread = new Thread(new ThreadStart(PerformActionWithTimer));
thread.Start();

void PerformActionWithTimer()
{
   //Timer inside this
}
Mohamed
  • 470
  • 3
  • 14

3 Answers3

2

There's no such thing as a System.Windows.Timer. Presumably you mean a System.Windows.Forms.Timer. Don't ever try to use that class in a multi-threading scenario. It raises its Tick event on the UI thread and that's it. If you want a timer to raise events on a secondary thread then use a System.Timers.Timer. There's no real reason to use the System.Threading.Timer directly at all.

jmcilhinney
  • 50,448
  • 5
  • 26
  • 46
  • I modified my question. I was about to ask this. by mistake i typed wrongly – Mohamed Aug 05 '14 at 06:41
  • I don't mean not to use a WinForms `Timer` in an application that uses multiple threads. I mean don;t ever try to use a WinForms `Timer` where it needs to have knowledge of multiple threads. As far as the WinForms `Timer` is concerned, there is only one thread: the UI thread. – jmcilhinney Aug 05 '14 at 07:45
  • Have you bothered to read the documentation? "A Timer is used to raise an event at user-defined intervals. This Windows timer is designed for a single-threaded environment where UI threads are used to perform processing. It requires that the user code have a UI message pump available and always operate from the same thread, or marshal the call onto another thread". There's no ambiguity there. – jmcilhinney Aug 05 '14 at 07:46
  • Because there's an expectation of effort on your part here and if you haven't used the Help menu then you really haven't made what I would consider a satisfactory effort. – jmcilhinney Aug 05 '14 at 09:12
2

I very strongly urge you not to use System.Timers.Timer, primarily due to this little bit of information from the Remarks section in the MSDN documentation.

The Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event.

Which means that if your timer's elapsed event throws an exception that you don't explicitly catch, the exception will get swallowed and you'll never know that something bad happened.

Consider this Elapsed event handler:

static void MyTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Console.WriteLine("Badness! Throwing exception");
    throw new ApplicationException("something bad happened");
}

Clearly, the intention here is to kill the program immediately because it encountered an unrecoverable error. But the exception will never escape to the main program. The timer handler in .NET does essentially this:

try
{
    MyTimer_Elapsed(sender, args);
}
catch
{
    // Why would anybody want to know that something bad happened?
}

It's a bug hider and as a result I won't use it.

In addition, there's no way to specify a context object that will be supplied in the event arguments, like there is with the Windows Forms timer (the Tag property) or System.Threading.Timer (the state parameter passed to the constructor).

System.Timers.Timer is a broken and limited component wrapper around System.Threading.Timer. Its two conveniences (the component wrapper and the SynchronizingObject) are far outweighed by its idiotic exception swallowing and the lack of a user context object. Don't use it. Use System.Threading.Timer instead.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
1

It depends. The System.Timers.Timer has two modes of operation.

If SynchronizingObject is set to an ISynchronizeInvoke instance then the Elapsed event will execute on the thread hosting the synchronizing object. Usually these ISynchronizeInvoke instances are none other than plain old Control and Form instances that we are all familiar with. So in that case the Elapsed event is invoked on the UI thread and it behaves similar to the System.Windows.Forms.Timer. Otherwise, it really depends on the specific ISynchronizeInvoke instance that was used.

If SynchronizingObject is null then the Elapsed event is invoked on a ThreadPool thread and it behaves similar to the System.Threading.Timer. In fact, it actually uses a System.Threading.Timer behind the scenes and does the marshaling operation after it receives the timer callback if needed.

In your specific case the System.Timers.Timer that you have created does not have a synchronizing object assigned so it will behave the same as a System.Threading.Timer.

Brian Gideon
  • 47,849
  • 13
  • 107
  • 150