ASP .Net Core整合定时任务框架Quartz
简介
Quartz是一款优秀的定时任务框架,为应用程序中进行作业调度提供了简单却强大的机制。允许程序开发人员根据时间的间隔来调度作业。实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。Quartz最初是使用Java开发的,现在也提供了.Net Core的版本。
Quartz.Net的官方网站文档:
安装
在.Net Core中安装Quartz非常简单,首先打开Visual Studio,选中项目右键选择管理Nuget程序包,搜索Quartz并点击安装即可(Ps:国内下载安装可能需要科学上网)
使用方法
Quartz的使用非常简单,参照官方文档,我们首先需要到Startup.cs里面增加Quartz启动项,然后自己定义一个Job(任务)里面实现自己要执行的逻辑,最后配置Job的启动时间,下次程序到达指定事件就会自动执行你的任务了。
- 配置StartUp启动项
打开项目,搜索startup.cs,修改ConfigureServices函数里里面的内容,可以参照下面的代码进行修改,
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// base configuration from appsettings.json
services.Configure<QuartzOptions>(Configuration.GetSection("Quartz"));
// if you are using persistent job store, you might want to alter some options
services.Configure<QuartzOptions>(options =>
{
options.Scheduling.IgnoreDuplicates = true; // default: false
options.Scheduling.OverWriteExistingData = true; // default: true
});
services.AddQuartz(q =>
{
// handy when part of cluster or you want to otherwise identify multiple schedulers
q.SchedulerId = "Scheduler-Core";
// we take this from appsettings.json, just show it's possible
// q.SchedulerName = "Quartz ASP.NET Core Sample Scheduler";
// as of 3.3.2 this also injects scoped services (like EF DbContext) without problems
q.UseMicrosoftDependencyInjectionJobFactory();
// or for scoped service support like EF Core DbContext
// q.UseMicrosoftDependencyInjectionScopedJobFactory();
// these are the defaults
q.UseSimpleTypeLoader();
q.UseInMemoryStore();
q.UseTimeZoneConverter();
q.UseDefaultThreadPool(tp =>
{
tp.MaxConcurrency = 10;
});
q.ScheduleJob<HelloJob>(trigger => trigger
.WithIdentity("Combined Configuration Trigger")
.StartNow()
.WithDailyTimeIntervalSchedule(x => x.WithInterval(30, IntervalUnit.Second))
.WithDescription("my awesome trigger configured for a job with single call")
);
// Quartz.Extensions.Hosting allows you to fire background service that handles scheduler lifecycle
services.AddQuartzHostedService(options =>
{
// when shutting down we want jobs to complete gracefully
options.WaitForJobsToComplete = true;
});
- 定义自己的job
创建一个类文件,继承IJob接口,实现Execute方法,当定时任务执行的时候,Execute方法会自动执行。参考代码如下:
public class HelloJob : IJob
{
public virtual async Task Execute(IJobExecutionContext context)
{
//在这里面实现你的逻辑
}
}
- 绑定自己的job,定义触发时间
在第一步的q.ScheduleJob已经定义了触发时间和绑定的job
q.ScheduleJob<HelloJob>(trigger => trigger
.WithIdentity("Combined Configuration Trigger")
.StartNow()
.WithDailyTimeIntervalSchedule(x => x.WithInterval(30, IntervalUnit.Second))
.WithDescription("my awesome trigger configured for a job with single call")
WithDailyTimeIntervalSchedule函数定义了触发周期,里面是以Lambda函数的形式来定义,如果想使用crontab来定义触发时间请使用.WithCronSchedule进行替换
.WithCronSchedule("0/3 * * * * ?")
- 附加说明
到这里一般的定时任务都可以实现了,但是如果你想要在定时任务里面操作数据库,你需要将Service注入到Job里面,在Quartz 3.0之前还不能这样做,只能使用JobFactory做一系列操作才能实现非常复杂,Quartz 3.0以后,可以直接使用构造函数的方式进行注入了。
public class HelloJob : IJob
{
private readonly IService _Service;
public HelloJob(IService Service)
{
_IService = Service;
}
public virtual async Task Execute(IJobExecutionContext context)
{
//你要实现的逻辑
}
}
}
如果你使用的是ASP .Net Core APB框架开发,因为APB框架使用CurrentUnitWork来控制数据库的事务处理,所以上述语句在操作数据库时会报错 找不到UnitWork,你需要加几个注解和一条语句来控制事务处理
[UnitOfWork]
public class HelloJob : IJob
{
private readonly IService _Service;
private readonly IUnitOfWorkManager _unitOfWorkManager;
public HelloJob(IService Service,, IUnitOfWorkManager unitOfWorkManager)
{
_IService = Service;
_unitOfWorkManager = unitOfWorkManager;
}
public virtual async Task Execute(IJobExecutionContext context)
{
//你需要实现的非数据库逻辑
using (var unitOfWork = _unitOfWorkManager.Begin())
{
//你要实现的数据库逻辑
unitOfWork.Complete();
}
}
}
}
{{item.content}}
@{{item.nickName}} {{item2.content}}
目录