.NET6 Quartz执行定时Job 入门

第一步:安装Nuget包

分别安装QuartzQuartz.AspNetCoreQuartz.Extensions.DependencyInjection

第二步:程序入口配置

public class Program
{
	public static void Main(string[] args)
	{
		var builder = WebApplication.CreateBuilder(args);

		//读取配置和初始化Log
		builder.Services.AddSingleton(new ConfigHelper(builder.Configuration));
		builder.Services.AddSingleton(new LogHelper());
		CustomParameter.CAPConnectionString = ConfigHelper.GetConnectionString("CAP_Master");

		//API配置
		builder.Services.AddControllers();
		builder.Services.AddEndpointsApiExplorer();
		builder.Services.AddSwaggerGen();

		//Job相关配置
		builder.Services.AddQuartz(q =>
		{
			q.UseMicrosoftDependencyInjectionScopedJobFactory();
		});

		builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
		builder.Services.AddTransient<SampleJob>();
		builder.Services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
		builder.Services.AddSingleton<IJobFactory, SingletonJobFactory>();
		builder.Services.AddSingleton<QuartzSchedulerService>();

		//HttpClient
		builder.Services.AddHttpClient();
		builder.Services.AddTransient<HttpClientHelper>();

		CustomParameter.CAPConnectionString = ConfigHelper.Get("ConnectionStrings:CAP_Master");

		//允许跨域访问
		builder.Services.AddCors(options =>
		{
			options.AddPolicy(name: "MyPolicy",
							  builder => builder.AllowAnyOrigin()
									  .AllowAnyMethod()
									  .AllowAnyHeader());
		});

		var app = builder.Build();

		// Configure the HTTP request pipeline.
		if (app.Environment.IsDevelopment())
		{
		}

		app.UseCors("MyPolicy"); // 应用CORS策略
		app.UseSwagger();
		app.UseSwaggerUI();
		app.UseHttpsRedirection();
		app.UseAuthorization();
		app.MapControllers();

		app.Run();
	}
}

第三步:配置Service

配置QuartzSchedulerService

public class QuartzSchedulerService
{
	private readonly ISchedulerFactory _schedulerFactory;
	private IScheduler? _scheduler;
	private readonly IServiceProvider _serviceProvider;
	private const string JOB_GROUP_NAME = "SyncSiteAndUserJobGroup";
	private const string JOB_TRIGGER = "SyncSiteAndUserJobTrigger";


	public QuartzSchedulerService(ISchedulerFactory schedulerFactory, IServiceProvider serviceProvider)
	{
		_schedulerFactory = schedulerFactory;
		_serviceProvider = serviceProvider;
		InitializeScheduler().GetAwaiter().GetResult();


	}

	private async Task InitializeScheduler()
	{
		_scheduler = await _schedulerFactory.GetScheduler();
		_scheduler.JobFactory = new SingletonJobFactory(_serviceProvider); // 设置DI容器来解析Job的依赖  

		if (_scheduler != null && !_scheduler.IsStarted)
		{
			await _scheduler.Start();  // 启动调度器
		}
	}

	/// <summary>
	/// Job启动
	/// </summary>
	/// <returns></returns>
	public async Task<ReturnBase> Start()
	{
		ReturnBase rb = new ReturnBase();
		try
		{
			SampleJob.IsStopTask = false;
			//获取任务设定
			MicroCAP_ScheduledTask task = ConfigManage.GetScheduledTaskModel();

			//改用使用DI容器创建Job
			var job = JobBuilder.Create<SampleJob>()
					.WithIdentity(task.TaskID, JOB_GROUP_NAME)
					.Build();

			//开始后立即执行的触发器
			var triggerNow = TriggerBuilder.Create()
				.WithIdentity(task.TaskID + "Now", JOB_TRIGGER)
				.StartNow()
				.Build();

			//开始后按配置时间执行的触发器
			var triggerCron = TriggerBuilder.Create()
				.WithIdentity(task.TaskID + "Cron", JOB_TRIGGER)
				.WithCronSchedule(task.SyncTime)
			.Build();

			if (_scheduler != null)
			{
				await _scheduler.ScheduleJob(job, new HashSet<ITrigger>() { triggerNow, triggerCron }, true);
			}

			return rb.Ok();
		}
		catch (Exception ex)
		{
			LogHelper.Error("Job启动异常:" + ex.ToString());
			return rb.Error(500, "Job启动异常:" + ex.Message);
		}
	}

	/// <summary>
	/// 停止Job执行
	/// </summary>
	/// <returns></returns>
	public async Task<ReturnBase> Stop()
	{
		ReturnBase rb = new ReturnBase();
		try
		{
			if (_scheduler != null)
			{
				//获取任务设定
				MicroCAP_ScheduledTask task = ConfigManage.GetScheduledTaskModel();
				//获取JobKey
				JobKey jobKey = new JobKey(task.TaskID, JOB_GROUP_NAME); //使用之前设定的组名
				//删除Job
				if (await _scheduler.CheckExists(jobKey))
				{
					await _scheduler.DeleteJob(jobKey);
				}

				SampleJob.IsStopTask = true;
				return rb.Ok();
			}
			else
			{
				return rb.Error(0, "任务调度服务已停止");
			}
		}
		catch (Exception ex)
		{
			LogHelper.Error("Job停止异常:" + ex.ToString());
			return rb.Error(500, "Job停止异常:" + ex.Message);
		}
	}

	/// <summary>
	/// 获取Job执行状态
	/// </summary>
	/// <returns></returns>
	public async Task<ReturnBase> GetJobStatus()
	{
		ReturnBase rb = new ReturnBase();
		try
		{
			if (_scheduler != null)
			{
				MicroCAP_ScheduledTask task = ConfigManage.GetScheduledTaskModel();

				TriggerKey triggerKey = new TriggerKey(task.TaskID + "Now", JOB_TRIGGER);
				TriggerState state = await _scheduler.GetTriggerState(triggerKey);

				//LogHelper.Info(task.TaskID + "Now - " + state.ToString());
				//如果Now不存在,则查找Cron
				if (state == TriggerState.Normal || state == TriggerState.Blocked)
				{
					return rb.Ok(null, "running");
				}
				else
				{
					if (state == TriggerState.None || state == TriggerState.Complete)
					{
						TriggerKey triggerKeyCron = new TriggerKey(task.TaskID + "Cron", JOB_TRIGGER);
						TriggerState stateCron = await _scheduler.GetTriggerState(triggerKeyCron);

						//LogHelper.Info(task.TaskID + "Cron - " + stateCron.ToString());
						if (stateCron == TriggerState.Normal || stateCron == TriggerState.Complete || stateCron == TriggerState.Blocked)
						{
							return rb.Ok(null, "running");
						}
						else
						{
							return rb.Ok(null, "stopped");
						}
					}
					else
					{
						return rb.Ok(null, "stopped");
					}
				}
			}
			return rb.Ok(null, "stopped");
		}
		catch (Exception ex)
		{
			LogHelper.Error("获取任务状态异常:" + ex.ToString());
			return rb.Error(500, "获取任务状态异常" + ex.Message);
		}
	}

}

配置SingletonJobFactory

public class SingletonJobFactory : IJobFactory
{
	private readonly IServiceProvider _serviceProvider;

	public SingletonJobFactory(IServiceProvider serviceProvider)
	{
		_serviceProvider = serviceProvider;
	}

	public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
	{
		return _serviceProvider.GetRequiredService(bundle.JobDetail.JobType) as IJob;
	}

	public void ReturnJob(IJob job)
	{
		// 这里可以添加释放作业的逻辑(如果需要)  
		(job as IDisposable)?.Dispose();
	}
}

第四步:创建Job执行的逻辑

//DisallowConcurrentExecution 可限制单线程执行
[DisallowConcurrentExecution]
public class SampleJob : IJob
{
    private readonly HttpClientHelper _httpclient;
    public static bool IsStopTask = false;
    private readonly IWebHostEnvironment _env;

    public SampleJob(HttpClientHelper httpClientHelper, IWebHostEnvironment env)
    {
        _httpclient = httpClientHelper;
        _env = env;
    }

    public Task Execute(IJobExecutionContext context)
    {
        //这里创建Job执行逻辑
	   //获取程式根目录(读取文件使用)
	   var rootPath = _env.ContentRootPath;

	   //_httpclient 访问API

        return Task.CompletedTask;
    }

    /// <summary>
    /// 
    /// </summary>
    private void SendMail(SyncJobReport rp)
    {
        //省略...
    }

    /// <summary>
    /// 强行中止任务,抛出自定义异常
    /// </summary>
    /// <exception cref="OperationCanceledException"></exception>
    public void Discontinue()
    {
        if (IsStopTask) throw new OperationCanceledException();
    }
}

第五步:创建APIController

[Route("api/[controller]/[action]")]
[ApiController]
public class SchedulerController : ControllerBase
{
	private readonly QuartzSchedulerService _schedulerService;

	public SchedulerController(QuartzSchedulerService schedulerService)
	{
		_schedulerService = schedulerService;
	}

	[HttpPost("start")]
	public async Task<IActionResult> Start()
	{
		return Ok(await _schedulerService.Start());
	}

	[HttpPost("stop")]
	public async Task<IActionResult> Stop()
	{
		return Ok(await _schedulerService.Stop());
	}

	[HttpGet("status")]
	public async Task<IActionResult> Status()
	{
		return Ok(await _schedulerService.GetJobStatus());
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值