Windows Service to run a function at specified tim

2020-02-02 05:53发布

I wanted to start a Windows service to run a function everyday at specific time.

What method i should consider to implement this? Timer or using threads?

7条回答
Animai°情兽
2楼-- · 2020-02-02 06:30

if it is one in a day, why you don't use task scheduler? windows service is useful when you want run task many time in minute. so if you want to run a program in a specific time, its better to use task scheduler and set event of task scheduler on a specific time in day. I do many thing with task scheduler and its perfect. you can set rout of program in task scheduler and set interval time to run it. if you want to run a program every 5 min in a day still you can use task scheduler and its better way.

查看更多
beautiful°
3楼-- · 2020-02-02 06:32

Good answer (I used your code), but one problem with this line:

_timer.Interval = _scheduleTime.Subtract(DateTime.Now).TotalSeconds * 1000;

If DateTime.now is later than scheduleTime, you will go negative and this will generate an exception when assigning to timer.Interval.

I used:

if (DateTime.now > scheduleTime)
    scheduleTime = scheduleTime.AddHours(24);

Then do the subtraction.

查看更多
可以哭但决不认输i
4楼-- · 2020-02-02 06:36

Are you sure, you need a service, that runs only one time per day?

Maybe Windows Task Schedule will be better solution?

查看更多
爷、活的狠高调
5楼-- · 2020-02-02 06:38

(1) On first start, Set _timer.Interval to the amount of milliseconds between the service start and schedule time. This sample set schedule time to 7:00 a.m. as _scheduleTime = DateTime.Today.AddDays(1).AddHours(7);

(2) On Timer_Elapsed, reset _timer.Interval to 24 hours (in milliseconds) if current interval is not 24 hours.

System.Timers.Timer _timer;
DateTime _scheduleTime; 

public WinService()
{
    InitializeComponent();
    _timer = new System.Timers.Timer();
    _scheduleTime = DateTime.Today.AddDays(1).AddHours(7); // Schedule to run once a day at 7:00 a.m.
}

protected override void OnStart(string[] args)
{           
    // For first time, set amount of seconds between current time and schedule time
    _timer.Enabled = true;
    _timer.Interval = _scheduleTime.Subtract(DateTime.Now).TotalSeconds * 1000;                                          
    _timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
}

protected void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    // 1. Process Schedule Task
    // ----------------------------------
    // Add code to Process your task here
    // ----------------------------------


    // 2. If tick for the first time, reset next run to every 24 hours
    if (_timer.Interval != 24 * 60 * 60 * 1000)
    {
        _timer.Interval = 24 * 60 * 60 * 1000;
    }  
}

Edit:

Sometimes people want to schedule the service to start at day 0, not tomorrow so they change DateTime.Today.AddDays(0).If they do that and set a time in the past it causes an error setting the Interval with a negative number.

//Test if its a time in the past and protect setting _timer.Interval with a negative number which causes an error.
double tillNextInterval = _scheduleTime.Subtract(DateTime.Now).TotalSeconds * 1000;
if (tillNextInterval < 0) tillNextInterval += new TimeSpan(24, 0, 0).TotalSeconds * 1000;
_timer.Interval = tillNextInterval;
查看更多
干净又极端
6楼-- · 2020-02-02 06:38

Use Windows built in Task Scheduler (http://windows.microsoft.com/en-us/windows7/schedule-a-task) or Quartz.net.

Unless ... you have a service that's doing lots of other processing and needs to be running all the time in which case a Timer might be appropriate.

查看更多
手持菜刀,她持情操
7楼-- · 2020-02-02 06:43
private static double scheduledHour = 10;
private static DateTime scheduledTime;

public WinService()
{
     scheduledTime = DateTime.Today.AddHours(scheduledHour);//setting 10 am of today as scheduled time- service start date
}

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
      DateTime now = DateTime.Now;
      if (scheduledTime < DateTime.Now)
      {
         TimeSpan span = now - DateTime.Now;
         scheduledTime = scheduledTime.AddMilliseconds(span.Milliseconds).AddDays(1);// this will set scheduled time to 10 am of next day while correcting the milliseconds
         //do the scheduled task here
      }  
}
查看更多
登录 后发表回答