15

I have a messaging aspect of my application using Jabber-net (an XMPP library.)

What I would like to do, if for some reason the connection to the Server is ended, is keep trying to connect every minute or so.

If I start a Timer to wait for a period of time before the next attempt, does that timer run asynchronously and the resulting Tick event join the main thread, or would I need to start my own thread and start the timer from within there?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MrEdmundo
  • 5,105
  • 13
  • 46
  • 58

3 Answers3

38

What kind of timer are you using?

  • System.Windows.Forms.Timer will execute in the UI thread
  • System.Timers.Timer executes in a thread-pool thread unless you specify a SynchronizingObject
  • System.Threading.Timer executes its callback in a thread-pool thread

In all cases, the timer itself will be asynchronous - it won't "take up" a thread until it fires.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Remember if you are not using the System.Windows.Forms.Timer that accessing a Control will throw an Exception unless you do the appropriate InvokeRequired check and invocation. – Byron Ross Apr 08 '09 at 09:14
  • You're right, In my question I should have said I wasn't sure which timer I should use. Looking at the three options you have supplied and reading MSDN the System.Timers.Timer looks like the right one for this case as on the Tick a call will need to be made to a object created in the main thread. – MrEdmundo Apr 08 '09 at 09:17
  • @Byron Ross: An alternative being System.Timers.Timer with the SynchronizingObject set to a control. – Jon Skeet Apr 08 '09 at 09:22
  • I consider the main thread to be the thread that the application is executing under and other threads are created from. Is the correct term for this UI Thread? – MrEdmundo Apr 08 '09 at 09:25
  • Well that depends on whether your app has a UI or not. ;). The whole UI thread business is based on apps that have a "main" UI (typically an Application.Run() somewhere). The sync rule is that you cannot access a UI control on a thread that didn't create the control. – Quibblesome Apr 08 '09 at 09:36
  • Yeah I understand that thanks, just trying to clarify it's the only way I learn. Just out of interest what is the "main" thread called for a non UI app? – MrEdmundo Apr 08 '09 at 09:39
  • Well, there's the thread which executes the Main() method. However, you'll need to run *some* sort of message pump (or something similar) if you want to be able to marshal calls to it. – Jon Skeet Apr 08 '09 at 10:04
  • The form timer will not be asynchronous. System.Windows.Forms.Timer The timer events raised by this timer class are synchronous with respect to the rest of the code in your Windows Forms app. This means that application code that is executing will never be preempted by an instance of this timer class (assuming you don't call Application.DoEvents). http://msdn.microsoft.com/en-us/magazine/cc164015.aspx – john k Feb 25 '14 at 03:58
  • @user396483: They're synchronous in that respect, yes - but in the context of the question, where the OP is worried that once he's started a timer it will block the thread until the timer fires, it's not synchronous. – Jon Skeet Feb 25 '14 at 06:56
  • What about the WPF-specific timer, the `DispatcherTimer`? I guess it also runs its event in the UI thread. – Alejandro Aug 08 '16 at 17:05
  • @Alejandro: Yes, it will. – Jon Skeet Aug 08 '16 at 21:04
1

The timer will effectively run in the background and cause events in your main thread to be executed.

cjk
  • 45,739
  • 9
  • 81
  • 112
1

I'm not sure how the Timers in .NET are implemented, but if they use the windows API for creating a timer the form message loop receives a WM_TIMER message and only when the form thread is not busy can it proces that request, so the timer would fire at the right time, but you could be stalling the UI thread. The timer would be started with the SetTimer API and the OS will make sure to post a WM_TIMER message.

I've checked, only System.Windows.Forms.Timer+TimerNativeWindow.StartTimer(Int32) depends on:

[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern IntPtr SetTimer(HandleRef hWnd, int nIDEvent, int uElapse, IntPtr lpTimerFunc);

So only this timer has the described "problem".

Davy Landman
  • 15,109
  • 6
  • 49
  • 73