using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Impl.Triggers;
using Quartz.Spi;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using VOL.Core.EFDbContext;
using VOL.Entity.DomainModels;
namespace VOL.Core.Quartz
{
///
/// Quartz 定时任务扩展:初始化、增删改、启停、立即执行。
/// Status 与 Quartz.TriggerState 对齐:0=Normal(运行), 1=Paused(暂停)。
///
public static class QuartzNETExtension
{
private const string DefaultGroup = "group";
private const string JobDataTaskId = "TaskId";
private static readonly ConcurrentDictionary TaskCache = new();
private static readonly SemaphoreSlim SchedulerLock = new(1, 1);
private static ISchedulerFactory _schedulerFactory;
private static IJobFactory _jobFactory;
public static IApplicationBuilder UseQuartz(this IApplicationBuilder applicationBuilder, IWebHostEnvironment env)
{
var services = applicationBuilder.ApplicationServices;
Initialize(
services.GetRequiredService(),
services.GetRequiredService());
var lifetime = services.GetRequiredService();
lifetime.ApplicationStarted.Register(() => _ = StartJobsAsync(lifetime.ApplicationStopping));
lifetime.ApplicationStopping.Register(() =>
ShutdownQuartzAsync().ConfigureAwait(false).GetAwaiter().GetResult());
return applicationBuilder;
}
internal static void Initialize(ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
{
_schedulerFactory = schedulerFactory;
_jobFactory = jobFactory;
}
///
/// 从数据库加载任务并注册到调度器
///
internal static async Task StartJobsAsync(CancellationToken cancellationToken = default)
{
try
{
await using var context = new VOLContext();
List tasks = await context.Set()
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
foreach (Sys_QuartzOptions options in tasks)
{
cancellationToken.ThrowIfCancellationRequested();
await options.AddJob(_schedulerFactory, _jobFactory).ConfigureAwait(false);
}
IScheduler scheduler = await GetSchedulerAsync(_schedulerFactory, _jobFactory).ConfigureAwait(false);
await EnsureStartedAsync(scheduler).ConfigureAwait(false);
Console.WriteLine($"Quartz 启动完成,共注册 {tasks.Count} 个作业");
}
catch (OperationCanceledException)
{
Console.WriteLine("Quartz 启动已取消");
}
catch (Exception ex)
{
Console.WriteLine($"作业启动异常:{ex.Message}{ex.StackTrace}");
QuartzFileHelper.Error($"作业启动异常:{ex.Message}{ex.StackTrace}");
}
}
public static async Task ShutdownQuartzAsync()
{
if (_schedulerFactory == null)
return;
try
{
IScheduler scheduler = await _schedulerFactory.GetScheduler().ConfigureAwait(false);
if (scheduler != null && !scheduler.IsShutdown)
{
await scheduler.Shutdown(waitForJobsToComplete: false).ConfigureAwait(false);
Console.WriteLine("Quartz 调度器已关闭");
}
}
catch (Exception ex)
{
Console.WriteLine($"Quartz Shutdown 异常:{ex.Message}");
}
}
///
/// 添加(或覆盖)作业。Status=1 加入后暂停;Status=0 保持运行。
///
public static async Task