views:

268

answers:

2

Hi, i have been using System.Timer to run a windows service but have come across the problem where the timer randomly doesnt fire. I checked it yesterday and it hadnt fired for over 2 hours when its meant to fire every 10 mins. I read this up on Google and apparently its a known problem, the answer being to change over to Threading.Timer. I havent used this before so was looking for some insight. My current code is as follows:

using System;
using System.Timers;
using System.ServiceProcess;

namespace Code
{
public partial class Service : ServiceBase
{
    Timer timer = new Timer();

    public Service()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
        timer.Interval = 10000;
        timer.Enabled = true;
    }

    protected override void OnStop()
    {
        timer.Enabled = false;
    }

    private void OnElapsedTime(object source, ElapsedEventArgs e)
    {
        timer.Enabled = false;
        // Run system code here
        timer.Interval = 600000;
        timer.Enabled = true;
    }
}

}

Basically, this normally works fine. The system starts the timer and fires after 10 seconds. It stops the timer, does the job, resets the timer for 10 minutes and enables it. For the most part this always works, but as mentioned randomly decides to stop working, probably due to system resources etc.

If anyone can help me convert this into a Threading.Timer it would be appreciated.

Thanks, Chris

A: 

http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

Scroll down to find the example.

jgauffin
+1  A: 

Here's my best guess - not got time to test it, sorry :(

using System;
using System.Threading;
using System.ServiceProcess;

namespace Code
{
    public partial class Service : ServiceBase
    {
        Timer timer;
        AutoResetEvent autoEvent;
        bool stopped = true;

        public Service()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            stopped = false;
            TimerCallback tcb = new TimerCallback(OnElapsedTime);
            timer = new Timer(tcb, null, 10000, 600000);
        }

        protected override void OnStop()
        {
            stopped = true;
            timer.Dispose();
        }

        private void OnElapsedTime(Object stateInfo)
        {
            if (stopped)
                return;

            // Run system code here
        }
    }
}
Codesleuth
I guess the OP wants `Timeout.Infinite` as interval and restarting the timer each time using `Change(600000, Timeout.Infinite)` each time **System Code** is finished (or maybe it's the mistake he's doing in his example - who knows :-D).
Jaroslav Jandek
Have I not got the usage of the constructor right? I just checked on the MSDN page and I thought I got it right :s
Codesleuth
Have just implemented this code and it seems to be working just fine. I set the interval to change each time it fires so it doesnt overlap an already running method. As Jaroslav mentioned i added in the following within the elapsedtime call:timer.Change(Timeout.Infinite, Timeout.Infinite); and afterwards timer.Change(600000, Timeout.Infinite);
Chris