Windows服务 - 如何在几个特定时间运行任务?

时间:2012-04-30 08:20:12

标签: c# windows-services

我正在运行Windows服务。在其中,任务目前每天晚上7点运行。 在上午9点45分,上午11点45分,下午2点,下午3点45分,下午5点和下午5点45分,以最佳方式运行它的最佳方式是什么。

我知道我可以安排运行该功能的任务,但我想知道如何在我的Windows服务中执行此操作。目前的代码如下:

private Timer _timer;
private DateTime _lastRun = DateTime.Now;
private static readonly log4net.ILog log = log4net.LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

protected override void OnStart(string[] args)
{
    // SmartImportService.WebService.WebServiceSoapClient test = new WebService.WebServiceSoapClient();
    // test.Import();
     log.Info("Info - Service Started");
    _timer = new Timer(10 * 60 * 1000); // every 10 minutes??
    _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    _timer.Start();
}

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    log.Info("Info - Check time");
    DateTime startAt = DateTime.Today.AddHours(19);
    if (_lastRun < startAt && DateTime.Now >= startAt)
    {
        // stop the timer 
        _timer.Stop();               

        try
        {
           log.Info("Info - Import");
           SmartImportService.WebService.WebServiceSoapClient test = new WebService.WebServiceSoapClient();
           test.Import();
        }
        catch (Exception ex) {
           log.Error("This is my error - ", ex);
        }
        _lastRun = DateTime.Now;
        _timer.Start();
   }
}

4 个答案:

答案 0 :(得分:5)

考虑使用Quartz.netCronTrigger

答案 1 :(得分:5)

如果您不想使用cron或quartz,请编写一个函数来查找现在和下一次运行之间的时间间隔并相应地重置计时器,在服务启动和timeelapsed事件上调用此函数。你可能会做这样的事情(代码未经过测试)

   System.Timers.Timer _timer;
    List<TimeSpan> timeToRun = new List<TimeSpan>();
    public void OnStart(string[] args)
    {

        string timeToRunStr = "20:45;20:46;20:47;20:48;20:49";
        var timeStrArray = timeToRunStr.Split(';');
        CultureInfo provider = CultureInfo.InvariantCulture;

        foreach (var strTime in timeStrArray)
        {
            timeToRun.Add(TimeSpan.ParseExact(strTime, "g", provider));
        }
        _timer = new System.Timers.Timer(60*100*1000);
        _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        ResetTimer();
    }


    void ResetTimer()
    {
        TimeSpan currentTime = DateTime.Now.TimeOfDay;
        TimeSpan? nextRunTime = null;
        foreach (TimeSpan runTime in timeToRun)
        {

            if (currentTime < runTime)
            {
                nextRunTime = runTime;
                break;
            }
        }
        if (!nextRunTime.HasValue)
        {
            nextRunTime = timeToRun[0].Add(new TimeSpan(24, 0, 0));
        }
        _timer.Interval = (nextRunTime.Value - currentTime).TotalMilliseconds;
        _timer.Enabled = true;

    }

    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        _timer.Enabled = false;
        Console.WriteLine("Hello at " + DateTime.Now.ToString());
        ResetTimer();
    }

答案 2 :(得分:0)

如果你清楚它应该运行什么时间表..那么在经过的时间事件中更改计时器的时间间隔,以便它按照计划运行..我从未尝试过

答案 3 :(得分:0)

我会使用后台线程并让它执行一个无限循环来完成你的工作并睡15分钟。服务代码比使用计时器更简洁,更简单。

请参阅MSDN上的this文章。