Reputation: 227
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
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
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
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
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