Windows Service to run a function at specified time

后端 未结 7 1838
一生所求
一生所求 2020-12-02 11:57

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条回答
  • 2020-12-02 12:09

    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.

    0 讨论(0)
  • 2020-12-02 12:11
    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
          }  
    }
    
    0 讨论(0)
  • 2020-12-02 12:18

    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.

    0 讨论(0)
  • 2020-12-02 12:19

    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.

    0 讨论(0)
  • 2020-12-02 12:25

    (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;
    
    0 讨论(0)
  • 2020-12-02 12:25

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

    Maybe Windows Task Schedule will be better solution?

    0 讨论(0)
提交回复
热议问题