Marko
Marko

Reputation: 227

Windows Service run every hour in specific minute

I need help. I have Windows Service and I need run this service every hour in specific minute for example: 09:05, 10:05, 11:05,.... My service now start every hour but every hour from time when i start this service. So how can I achieve my needs.

My code:

public partial class Service1 : ServiceBase
{
    System.Timers.Timer timer = new System.Timers.Timer();

    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        this.WriteToFile("Starting Service {0}");

        timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);

        timer.Interval = 60000;

        timer.Enabled = true;
    }

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

        this.WriteToFile("Stopping Service {0}");
    }

    private void OnElapsedTime(object source, ElapsedEventArgs e)
    {
        this.WriteToFile(" interval start {0}");
    } }

Upvotes: 6

Views: 13550

Answers (4)

Emad
Emad

Reputation: 3929

You have all you need just start the timer differently:

public partial class Service1 : ServiceBase
{
    System.Timers.Timer timer = new System.Timers.Timer();

    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        this.WriteToFile("Starting Service {0}");

        timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
        var excess = DateTime.Now.Minute - 5;
        var span = DateTime.Now.AddMinutes(excess <= 0 ? -excess : 60- excess) - DateTime.Now;
        timer.Interval = span.TotalMilliseconds;

        timer.Enabled = true;
    }

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

        this.WriteToFile("Stopping Service {0}");
    }

    private void OnElapsedTime(object source, ElapsedEventArgs e)
    {
        var excess = DateTime.Now.Minute - 5;
        var span = DateTime.Now.AddMinutes(excess <= 0 ? -excess : 60- excess) - DateTime.Now;
        timer.Interval = span.TotalMilliseconds;
        this.WriteToFile(" interval start {0}");
    } 
}

This way you set for the first "x:05" minute and then every hour.

Upvotes: 0

Rufus L
Rufus L

Reputation: 37020

Here's another way you can calculate the first interval:

var minutesAfterHourToStart = 5;  // Start at 5 minutes after the hour

var now = DateTime.Now;
var minutesToStart = 60 - (now.Minute - (minutesAfterHourToStart - 1));
if (minutesToStart > 60) minutesToStart -= 60;
var secondsToStart = 60 - now.Second + (minutesToStart * 60);

timer.Interval = TimeSpan.FromSeconds(secondsToStart).TotalMilliseconds;

Then, in the OnTimeElapsed event, you would set the interval to run every hour. To prevent constantly setting the variable to the same value over and over, we could set a global variable that we've already set the final interval:

class MyService
{
    private bool resetInterval = true;

Then we can check this and set it to false the first time through:

private void OnElapsedTime(object source, ElapsedEventArgs e)
{
    if (resetInterval)
    {
        timer.Interval = TimeSpan.FromHours(1).TotalMilliseconds;
        resetInterval = false;
    }

Upvotes: 2

daniell89
daniell89

Reputation: 2272

Maybe just leave your code like it is, and set your service to start manually, then use windows scheduler to start it one time at specific hour. The rest work will do timer and OnElapse method; This could help you: https://stackoverflow.com/a/36309450/5358389

Upvotes: 0

Ivan Kishchenko
Ivan Kishchenko

Reputation: 815

You should check current time every 'n' seconds (1 as example) from timer:

public partial class Service1 : ServiceBase
{
    System.Timers.Timer timer = new System.Timers.Timer();

    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        this.WriteToFile("Starting Service {0}");

        timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);

        timer.Interval = 1000; // 1000 ms => 1 second

        timer.Enabled = true;
    }

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

        this.WriteToFile("Stopping Service {0}");
    }

    private int lastHour = -1;
    private void OnElapsedTime(object source, ElapsedEventArgs e)
    {
        var curTime = DateTime.Now; // Get current time
        if (lastHour != curTime.Hour && curTime.Minute == 5) // If now 5 min of any hour
        {
            lastHour = curTime.Hour;

            // Some action
            this.WriteToFile(" interval start {0}");
        }
    } 
}

Upvotes: 10

Related Questions