Problems with function called by System.Threading.Timer

49 Views Asked by At

I created a Windows service that runs some tasks from time to time so I used System.Threading.Timer. But on some occasions, I noticed that the function stops being called.

I checked by writing to a log file that you can check where the program is possibly stopping. All executions of the called function are finished, but at some point it stops being called

Here's my code:

namespace Service
{
    public partial class Service: ServiceBase
    {
        protected override void OnStart(string[] args)
        {
            // do some stuff
            log("Service Started"); // function that write in .txt file
            // define delay and execution interval
            Timer timer = new Timer(this.OnTimer, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(60));
        }
        
        public void OnTimer(object state)
        {
            log("Function fired"); 

            // do something

            log("Function closed");
        }
        
        protected override void OnStop()
        {
            log("Service stopped");
        }
    }
}

What do I need to investigate or do to ensure the function is always called? Thanks a lot!

1

There are 1 best solutions below

0
rotabor On
  1. Check "Function closed" per each "Function fired".
  2. Check "log" doesn't break.
  3. Run a task in OnTimer to isolate the executed code from the timer.
  4. Dispose the timer on stop. It requires a class field which also prevents the timer to be disposed by the garbage collector.
  5. Envolve error handling to track errors and to prevent the service to crash.
namespace Service {
    public partial class Service: ServiceBase {
        Timer _timer;
        protected override void OnStart(string[] args) {
            // do some stuff
            log("Service Started"); // function that write in .txt file
            // define delay and execution interval
            _timer = new Timer(OnTimer, null, 5000, 60000);
        }
        public void OnTimer(object state) {
            Task.Run(() => {
                try {
                    log("Function fired"); 
                    // do something
                    log("Function closed");
                }
                catch (Exception ex) { log(ex.ToString()); }
            });
        }
        protected override void OnStop() {
            _timer.Dispose();
            log("Service stopped");
        }
    }
}