using Quartz;
using Quartz.Spi;
using System.ComponentModel.DataAnnotations;
namespace EFCoreTest.job
{
//启动注入服务
public class QuartzService : BackgroundService
{
//创建一个调度器
private readonly IScheduler _scheduler;
private Task<IScheduler> _schedulers;
private readonly IJobFactory _jobFactory;
public QuartzService(IScheduler scheduler)
{
_scheduler = scheduler;
}
public override async Task StartAsync(CancellationToken cancellationToken)
{
DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(DateTime.Now, 2);
DateTimeOffset endTime = DateBuilder.NextGivenMinuteDate(DateTime.Now, 50);
IJobDetail job1 = JobBuilder.Create<JobListenIIS>()
.WithIdentity("MyJob", "group")
.Build();
ICronTrigger cronTrigger1 = (ICronTrigger)TriggerBuilder.Create()
//.StartAt(startTime)
//.EndAt(endTime)
.WithIdentity("MyJob", "group")
.WithCronSchedule("0 */1 * * * ?")
// .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(15, 01)) //每日的08:30执行
.Build();
//把Job和触发器放入调度器中
await _scheduler.ScheduleJob(job1, cronTrigger1);
await _scheduler.Start(cancellationToken);
}
/// <summary>
/// 停止计划任务
/// </summary>
/// <returns></returns>
public override async Task StopAsync(CancellationToken cancellationToken)
{
await _scheduler.Shutdown(cancellationToken);
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
throw new NotImplementedException();
}
#region 创建触发器帮助方法
/// <summary>
/// 创建SimpleTrigger触发器(简单触发器)
/// </summary>
/// <param name="tasksQz"></param>
/// <returns></returns>
private ITrigger CreateSimpleTrigger(SysTasks tasksQz)
{
if (tasksQz.RunTimes > 0)
{
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(tasksQz.ID, tasksQz.JobGroup)
.StartAt(tasksQz.BeginTime.Value)
.EndAt(tasksQz.EndTime.Value)
.WithSimpleSchedule(x => x.WithIntervalInSeconds(tasksQz.IntervalSecond)
.WithRepeatCount(tasksQz.RunTimes)).ForJob(tasksQz.ID, tasksQz.JobGroup).Build();
return trigger;
}
else
{
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(tasksQz.ID, tasksQz.JobGroup)
.StartAt(tasksQz.BeginTime.Value)
.EndAt(tasksQz.EndTime.Value)
.WithSimpleSchedule(x => x.WithIntervalInSeconds(tasksQz.IntervalSecond)
.RepeatForever()).ForJob(tasksQz.ID, tasksQz.JobGroup).Build();
return trigger;
}
// 触发作业立即运行,然后每10秒重复一次,无限循环
}
/// <summary>
/// 创建类型Cron的触发器
/// </summary>
/// <param name="tasksQz"></param>
/// <returns></returns>
private ITrigger CreateCronTrigger(SysTasks tasksQz)
{
// 作业触发器
return TriggerBuilder.Create()
.WithIdentity(tasksQz.ID, tasksQz.JobGroup)
.StartAt(tasksQz.BeginTime.Value)//开始时间
.EndAt(tasksQz.EndTime.Value)//结束数据
.WithCronSchedule(tasksQz.Cron)//指定cron表达式
.ForJob(tasksQz.ID, tasksQz.JobGroup)//作业名称
.Build();
}
private class SysTasks
{
/// <summary>
/// 描述 : 任务id
/// 空值 : False
/// 默认 :
/// </summary>
[Display(Name = "任务id")]
public string ID { get; set; }
/// <summary>
/// 描述 : 任务名称
/// 空值 : False
/// 默认 :
/// </summary>
[Display(Name = "任务名称")]
public string Name { get; set; }
/// <summary>
/// 描述 : 任务分组
/// 空值 : False
/// 默认 :
/// </summary>
[Display(Name = "任务分组")]
public string JobGroup { get; set; }
/// <summary>
/// 描述 : 运行时间表达式
/// 空值 : False
/// 默认 :
/// </summary>
[Display(Name = "运行时间表达式")]
public string Cron { get; set; }
/// <summary>
/// 描述 : 程序集名称
/// 空值 : False
/// 默认 :
/// </summary>
[Display(Name = "程序集名称")]
public string AssemblyName { get; set; }
/// <summary>
/// 描述 : 任务所在类
/// 空值 : False
/// 默认 :
/// </summary>
[Display(Name = "任务所在类")]
public string ClassName { get; set; }
/// <summary>
/// 描述 : 任务描述
/// 空值 : True
/// 默认 :
/// </summary>
[Display(Name = "任务描述")]
public string Remark { get; set; }
/// <summary>
/// 描述 : 执行次数
/// 空值 : False
/// 默认 : 0
/// </summary>
[Display(Name = "执行次数")]
public int RunTimes { get; set; }
/// <summary>
/// 描述 : 开始时间
/// 空值 : True
/// 默认 :
/// </summary>
[Display(Name = "开始时间")]
public DateTime? BeginTime { get; set; }
/// <summary>
/// 描述 : 结束时间
/// 空值 : True
/// 默认 :
/// </summary>
[Display(Name = "结束时间")]
public DateTime? EndTime { get; set; }
/// <summary>
/// 描述 : 触发器类型(0、simple 1、cron)
/// 空值 : False
/// 默认 : 1
/// </summary>
[Display(Name = "触发器类型(0、simple 1、cron)")]
public int TriggerType { get; set; }
/// <summary>
/// 描述 : 执行间隔时间(单位:秒)
/// 空值 : False
/// 默认 : 0
/// </summary>
[Display(Name = "执行间隔时间(单位:秒)")]
public int IntervalSecond { get; set; }
/// <summary>
/// 描述 : 是否启动
/// 空值 : False
/// 默认 : 0
/// </summary>
[Display(Name = "是否启动")]
public bool IsStart { get; set; }
/// <summary>
/// 最后运行时间
/// </summary>
public DateTime? LastRunTime { get; set; }
/// <summary>
/// api执行地址
/// </summary>
public string ApiUrl { get; set; }
/// <summary>
/// 任务类型 1、程序集 2、网络请求 3、SQL语句
/// </summary>
public int TaskType { get; set; }
/// <summary>
/// SQL语句
/// </summary>
public string SqlText { get; set; }
/// <summary>
/// 网络请求方式
/// </summary>
public string RequestMethod { get; set; }
}
#endregion 创建触发器帮助方法
}
}
using Quartz;
using Quartz.Spi;
using System.ComponentModel;
namespace EFCoreTest.job
{
/// <summary>
/// 通用执行计划类
/// </summary>
public class JobFactorys : IJobFactory
{
public IServiceProvider _serviceProvider;
/// <summary>
/// Type jobType, string cronExpression
/// </summary>
/// <exception cref="ArgumentNullException"></exception>
public JobFactorys(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
//this.JobType = jobType ?? throw new ArgumentNullException(nameof(jobType));
//CronExpression = cronExpression ?? throw new ArgumentNullException(nameof(cronExpression));
}
/// <summary>
/// Job类型
/// </summary>
public Type JobType { get; private set; }
/// <summary>
/// Cron表达式
/// </summary>
public string CronExpression { get; private set; }
/// <summary>
/// Job状态
/// </summary>
public JobStatus JobStatu { get; set; } = JobStatus.Init;
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
try
{
var job = _serviceProvider.GetService(bundle.JobDetail.JobType) as IJob;
return job;
}
catch (Exception e)
{
}
return null;
}
public void ReturnJob(IJob job)
{
var disposable = job as IDisposable;
disposable?.Dispose();
}
/// <summary>
/// 运行状态
/// </summary>
public enum JobStatus : byte
{
[Description("Initialization")]
Init = 0,
[Description("Running")]
Running = 1,
[Description("Scheduling")]
Scheduling = 2,
[Description("Stopped")]
Stopped = 3,
}
}
}
using EFCoreTest.socket;
using Fleck;
using Microsoft.AspNetCore.SignalR;
using Net6Test.KFK;
using Net6Test.socket;
using Quartz;
using System.Net.Sockets;
using System.Net.WebSockets;
namespace EFCoreTest.job
{
public class JobListenIIS : IJob
{
private readonly ClientWebSocket webSocket = new ClientWebSocket();
private readonly CancellationToken _cancellation = new CancellationToken();
public JobListenIIS(SocketsManager sockets)
{
Sockets = sockets;
}
public SocketsManager Sockets { get; set; }
private async void SendMsg(string msg)
{
// wSocket
WSocketClientHelp wSocketClient = new WSocketClientHelp("ws://localhost:60232/ws");
wSocketClient.Open(msg);
//调用接口定义的方法
//生产者 pub
}
/// <summary>
/// 调度方法
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public Task Execute(IJobExecutionContext context)
{
return Task.Run(() =>
{
SendMsg("系统通知");
});
}
}
}
#region 定时任务Job
//添加定时任务
builder.Services.AddSingleton<IJobFactory, JobFactorys>(); //Job工厂
builder.Services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();//注册ISchedulerFactory的实例
builder.Services.AddTransient<JobListenIIS>();
builder.Services.AddSingleton(p =>
{
var sf = new StdSchedulerFactory();
var scheduler = sf.GetScheduler().Result;
scheduler.JobFactory = p.GetService<IJobFactory>();
return scheduler;
});//注册ISchedulerFactory的实例。
builder.Services.AddHostedService<QuartzService>(); //注入服务
//IP和端口地址后缀输入 /QuartzUI
builder.Services.AddQuartzUI();
//添加本地调度任务访问
builder.Services.AddQuartzClassJobs();
#endregion