1:首先创建一个WebAPi
代码地址:Quartz代码
2:安装Quartz
3:创建文件夹和文件
4:复制代码
复制以后 看代码注释解释
JobFactory:
/// <summary>
/// 工作工厂
/// </summary>
public class JobFactory : IJobFactory
{
private readonly IServiceProvider _serviceProvider;
/// <summary>
/// 构造注入
/// </summary>
/// <param name="serviceProvider"></param>
public JobFactory(IServiceProvider serviceProvider) => _serviceProvider = serviceProvider;
/// <summary>
/// 创建一个指定类型的job
/// </summary>
/// <param name="bundle"></param>
/// <param name="scheduler"></param>
/// <returns></returns>
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
// 获得一个ioc对象,指定创建scope级别的实例
// 不写的话,默认是单例。
var serviceScope = _serviceProvider.CreateScope();
// 依赖注入一个 job 然后返回
return serviceScope.ServiceProvider.GetService(bundle.JobDetail.JobType) as IJob;
}
public void ReturnJob(IJob job)
{
}
JobSchedule:
/// <summary>
/// 任务计划表
/// </summary>
public class JobSchedule
{
public JobSchedule(Type jobType, string cronExpression)
{
JobType = jobType;
CronExpression = cronExpression;
}
/// <summary>
/// 作业类型
/// </summary>
public Type JobType { get; }
/// <summary>
/// cron 表达式
/// </summary>
public string CronExpression { get; }
}
QuartzHostedService:
/// <summary>
/// quartz 主机服务
/// </summary>
[DisallowConcurrentExecution]
public class QuartzHostedService : IHostedService //IHostedService 主机中注册托管服务
{
/// <summary>
/// 定时作业计划生成工厂
/// </summary>
private readonly ISchedulerFactory _schedulerFactory;
/// <summary>
/// 定时作业工厂
/// </summary>
private readonly IJobFactory _jobFactory;
/// <summary>
/// 定时作业计划集合,配合dotnet core的ioc注入进来
/// </summary>
private readonly IEnumerable<JobSchedule> _jobSchedules;
/// <summary>
/// 日志
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// quartz 调度器
/// </summary>
private IScheduler _scheduler;
/// <summary>
/// 构造注入
/// </summary>
/// <param name="schedulerFactory"></param>
/// <param name="jobFactory"></param>
/// <param name="jobSchedules"></param>
/// <param name="logger"></param>
public QuartzHostedService(ISchedulerFactory schedulerFactory, IJobFactory jobFactory, IEnumerable<JobSchedule> jobSchedules, ILogger<QuartzHostedService> logger)
{
_schedulerFactory = schedulerFactory;
_jobFactory = jobFactory;
_jobSchedules = jobSchedules;
_logger = logger;
}
/// <summary>
/// 批量启动定时任务
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task StartAsync(CancellationToken cancellationToken)
{
_scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
_scheduler.JobFactory = _jobFactory;
// 判断有没有记录,有的话,quartz会自动提取信息创建 schedule
foreach (var jobs in _jobSchedules)
{
var a = await _scheduler.CheckExists(new JobKey(GenerateIdentity(jobs, IdentityType.Job)));
var b = await _scheduler.CheckExists(new TriggerKey(GenerateIdentity(jobs, IdentityType.Trigger)));
if (!a && !b)
{
//创建定时作业
var job = CreateJob(jobs);
//创建触发器
var trigger = CreateTrigger(jobs);
await _scheduler.ScheduleJob(job, trigger, cancellationToken);
}
}
await _scheduler.Start();
}
/// <summary>
/// 创建触发器
/// </summary>
/// <param name="schedule"></param>
/// <returns></returns>
private static ITrigger CreateTrigger(JobSchedule schedule)
{
return TriggerBuilder
.Create()
.WithIdentity(GenerateIdentity(schedule, IdentityType.Trigger))
.WithCronSchedule(schedule.CronExpression)
.WithDescription(schedule.JobType.FullName)
.Build();
}
/// <summary>
/// 创建定时作业
/// </summary>
/// <param name="schedule"></param>
/// <returns></returns>
private static IJobDetail CreateJob(JobSchedule schedule)
{
return JobBuilder.Create(schedule.JobType).WithIdentity(GenerateIdentity(schedule, IdentityType.Job)).WithDescription(schedule.CronExpression).Build();
}
/// <summary>
/// 停止
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public Task StopAsync(CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
/// <summary>
/// 生成一个标识
/// </summary>
/// <param name="schedule"></param>
/// <param name="identityType">标识类型,一个job作业,或者是trigger触发器</param>
/// <returns></returns>
private static string GenerateIdentity(JobSchedule schedule, IdentityType identityType)
{
switch (identityType)
{
case IdentityType.Job:
return $"NdcPayInternal_Job_{schedule.JobType.Name}";
case IdentityType.Trigger:
return $"NdcPayInternal_Trigger_{schedule.JobType.Name}";
}
return schedule.JobType.FullName;
}
/// <summary>
/// 标识类型
/// </summary>
private enum IdentityType
{
Job,
Trigger
}
}
Program:
//任务计划
//-------------------------------------
builder.Services.AddHostedService<QuartzHostedService>();
builder.Services.AddSingleton<IJobFactory, JobFactory>();
builder.Services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
//-------------------------------------
MyJob1:
public class MyJob1 : IJob
{
/// <summary>
/// 日志
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// 日志引擎 ILogger
/// </summary>
/// <param name="logger"></param>
public MyJob1(ILogger<MyJob1> logger)
=> _logger = logger;
public Task Execute(IJobExecutionContext context)
{
_logger.LogInformation(DateTime.Now.ToString() + " 执行了我,我是 【job1】");
return Task.CompletedTask;
}
}
MyJob2:
/// <summary>
/// 工作日志
/// </summary>
public class MyJob2 : IJob
{
private readonly ILogger logger;
public MyJob2(ILogger<MyJob1> _logger) => logger = _logger;
public Task Execute(IJobExecutionContext context)
{
//设置信息日志消息格式并写入该消息。
logger.LogInformation(DateTime.Now.ToString() + " 执行了我,我是 【job2】");
return Task.CompletedTask;
}
}
Program:
// 请求获取-(GC回收-主动释放) 每一次获取的对象都不是同一个
builder.Services.AddTransient<MyJob1>();
builder.Services.AddTransient(u => new JobSchedule(jobType: typeof(MyJob1), cronExpression: "0/10 * * * * ?"));
builder.Services.AddTransient<MyJob2>();
builder.Services.AddTransient(u => new JobSchedule(jobType: typeof(MyJob2), cronExpression: "0/15 * * * * ?"));
//-------------------------------------
5:进行调试并查看控制台
本文来自博客园,作者:Sleepy-Person,转载请注明原文链接:https://www.cnblogs.com/Sleepy-Person/p/16087462.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现