2

我有一个 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

4 回答 4

5

考虑使用Quartz.netCronTrigger

于 2012-04-30T08:29:34.397 回答
5

如果您不想使用 cron 或石英,请编写一个函数来查找现在和下一次运行之间的时间间隔并相应地重置计时器,在服务启动和 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();
    }
于 2012-04-30T08:40:42.227 回答
0

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

于 2012-04-30T08:25:05.197 回答
0

我会使用一个后台线程并让它执行一个无限循环来完成你的工作并休眠 15 分钟。对于服务代码来说,这将比使用计时器更干净、更简单。

请参阅MSDN 上的这篇文章。

于 2012-04-30T08:27:36.553 回答