.NET Windows Service with timer stops responding

12,952

Solution 1

Like many respondents have pointed out exceptions are swallowed by timer. In my windows services I use System.Threading.Timer. It has Change(...) method which allows you to start/stop that timer. Possible place for exception could be reentrancy problem - in case when tickTack_Elapsed executes longer than timer period. Usually I write timer loop like this:

    void TimeLoop(object arg)
    {
        stopTimer();

        //Do some stuff

        startTimer();
    }

You could also lock(...) your main loop to protect against reentrancy.

Solution 2

unhandled exceptions in timers are swallowed, and they silently kill the timer

wrap the body of your timer code in a try-catch block

Solution 3

I have seen this before with both timer, and looped services. Usually the case is that an exception is caught that stops the timer or looping thread, but does not restart it as part of the exception recovery.

To your other points... I dont think that there is anything "elegant" about the timer. For me its more straight forward to see a looping operation in code than timer methods. But Elegance is subjective.

Memory issue? Not if you write it properly. Maybe a processor burden if your Thread.Sleep() isn't set right.

Solution 4

http://support.microsoft.com/kb/842793

This is a known bug that has resurfaced in the Framework more than once.

The best known work-around: don't use timers. I've rendered this bug ineffective by doing a silly "while (true)" loop.

Your mileage may vary, so verify with your combination of OS/Framework bits.

Solution 5

Interesting issue. If it is truly just time related (i.e. not an exception), then I wonder if you can simply periodically recycle the timer - i.e.

private void tickTack_Elapsed(object sender, ElapsedEventArgs e)
{
    CheckForRecycle();
    // ... actual code
}

private void CheckForRecycle()
{
    lock(someLock) {
        if(++tickCount > MAX_TICKS) {
            tickCount = 0;
            tickTack.Stop();
            // re-create timer
            tickTack = new Timer(...);
            tickTack.Elapsed += ...
            tickTack.Start();
        }
    }
}

You could probably merge chunks of this with the OnStart / OnStop etc to reduce duplication.

Share:
12,952
Biri
Author by

Biri

Updated on July 06, 2022

Comments

  • Biri
    Biri almost 2 years

    I have a windows service written in c#. It has a timer inside, which fires some functions on a regular basis. So the skeleton of my service:

    public partial class ArchiveService : ServiceBase
    {
        Timer tickTack;
        int interval = 10;
        ...
     
        protected override void OnStart(string[] args)
        {
            tickTack = new Timer(1000 * interval);
    
            tickTack.Elapsed += new ElapsedEventHandler(tickTack_Elapsed);
            tickTack.Start();
        }
    
        protected override void OnStop()
        {            
            tickTack.Stop();
        }    
        
        private void tickTack_Elapsed(object sender, ElapsedEventArgs e)
        {
            ...
        }
    }
    

    It works for some time (like 10-15 days) then it stops. I mean the service shows as running, but it does not do anything. I make some logging and the problem can be the timer, because after the interval it does not call the tickTack_Elapsed function.

    I was thinking about rewrite it without a timer, using an endless loop, which stops the processing for the amount of time I set up. This is also not an elegant solution and I think it can have some side effects regarding memory.

    The Timer is used from the System.Timers namespace, the environment is Windows 2003. I used this approach in two different services on different servers, but both is producing this behavior (this is why I thought that it is somehow connected to my code or the framework itself).

    Does somebody experienced this behavior? What can be wrong?


    Edit:

    I edited both services. One got a nice try-catch everywhere and more logging. The second got a timer-recreation on a regular basis. None of them stopped since them, so if this situation remains for another week, I will close this question. Thank you for everyone so far.


    Edit:

    I close this question because nothing happened. I mean I made some changes, but those changes are not really relevant in this matter and both services are running without any problem since then. Please mark it as "Closed for not relevant anymore".