前段做一个网站需要后台跑定时任务,但没有虚机,只是云上的Web应用,所以采用了Quartz框架,它提供了很强大的定时任务管理功能。

首先定义一个Job,实现IJob接口,就是要定期执行的逻辑。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Quartz;

namespace test
{
    public class MyJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
          //your code here
        }
    }
}

然后我们写一个方法来启动Scheduler、配置需要执行的任务。Quartz提供了多种不同的触发器足以满足任何需求,具体可参考官方文档。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Quartz;
using Quartz.Impl;

namespace test
{
    public class JobScheduler
    {
        public static void Start()
        {
            //启动Scheduler,只需执行一次
            IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
            scheduler.Start();

            //创建每分钟执行一次的触发器
            var trigger = TriggerBuilder.Create()
                .StartNow()
                .WithSimpleSchedule(s => s.WithIntervalInMinutes(1).RepeatForever())
                .Build();

            //添加任务
            scheduler.ScheduleJob(JobBuilder.Create<MyJob>().Build(), trigger);
            //scheduler.ScheduleJob(JobBuilder.Create<AnotherJob>().Build(), anotherTrigger);
        }
    }
}

这段代码必须放在Global.asax中,调用后就会根据定义的触发器一直执行,如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace test
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            JobScheduler.Start();
        }
    }
}

特别注意

  • IIS中的网站收到第一次请求之前网站是不会启动的,Global.asax中的代码也不会执行,如果新部署的网站或更新了dll需要访问网站来启动。
  • Quartz在触发器满足条件时调用任务,不关心之前的任务是否执行完,所以定义好时间间隔。