C# Job定时任务

105 阅读3分钟
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