31

I'm really struggling with this. I'm creating a winforms application in visual studio and need a background timer that ticks once every half hour - the purpose of this is to pull down updates from a server.

I have tried a couple of different approaches but they have failed, either due to poor tutorial/examples, or to my own shortcomings in C#. I think it would be a waste of time to show you what I have tried so far as it seems what I tried was pretty far off the mark.

Does anyone know of a clear and simple way of implementing an asynchronous background timer that is easily understandable by a C# newbie?

Mike Baxter
  • 6,868
  • 17
  • 67
  • 115
  • 2
    I assume you are using `System.Timers.Timer`? – Jeremy Holovacs Apr 08 '13 at 12:52
  • 2
    In my opinion the most important question is: How much work will happen when the timer is run? What will the effect be on the repsponsivness of your program. Please note that all WinForms application run in one UI thread, if that thread gets busy suddenly pulling some data from a server your users might not like it, so the questions , do you need a multithreaded solution or not. – Siraf Apr 08 '13 at 12:55
  • It's not a particuarly heavy process. Just grabs a datatable from a server then runs some SQL based on the contents of the table. Most of the time nothing will be returned anyway. – Mike Baxter Apr 08 '13 at 13:03
  • @Terfi: Then it is better to use System.Windows.Forms.Timer and System.Windows.Threading.DispatcherTimer. These are handy because they execute their code on the GUI thread, thus not needing explicit Invoke calls. These timers are good for a quick periodic update of the GUI. If the code is more long-running, you should use the System.Threading.Timer with an explicit Invoke just for the update part – Sunil Apr 08 '13 at 13:25

3 Answers3

41
    // Create a 30 min timer 
    timer = new System.Timers.Timer(1800000);

    // Hook up the Elapsed event for the timer.
    timer.Elapsed += OnTimedEvent;

    timer.Enabled = true;


...

private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    // do stuff
}

with the usual caveats of: timer won't be hugely accurate and might need to GC.KeepAlive(timer)

See also: Why does a System.Timers.Timer survive GC but not System.Threading.Timer?

Ievgen
  • 4,261
  • 7
  • 75
  • 124
Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
11

Declare member variable in your form:

System.Timers.Timer theTimer;

On form load (or whatever other time you need to start update polling), do:

theTimer = new System.Timers.Timer(1800000);
theTimer.Elapsed += PollUpdates;
theTimer.Start();

Declare your PollUpdates member function like this:

private void PollUpdates(object sender, EventArgs e)
{
}
the_virt
  • 707
  • 4
  • 10
  • sorry for possible duplicate of answer from Mitch Wheat, I've posted it the same time :) – the_virt Apr 08 '13 at 13:02
  • Yeah but thanks anyway! Unfortunately I can only mark one answer as accepted and since mitch answered first, it's only fair I mark his one. But I've +1'd yours - thanks :) – Mike Baxter Apr 08 '13 at 13:11
10

I think you need to know about all timer classes. See Jon's answer below.

What kind of timer are you using?

  1. System.Windows.Forms.Timer will execute in the UI thread
  2. System.Timers.Timer executes in a thread-pool thread unless you specify a SynchronizingObject
  3. 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.

Source: Do .NET Timers Run Asynchronously?

Community
  • 1
  • 1
JSJ
  • 5,653
  • 3
  • 25
  • 32