• Quartz.NET 3.0


    Quartz.NET是一个强大、开源、轻量的作业调度框架,你能够用它来为执行一个作业而创建简单的或复杂的作业调度。Quartz.NET 3.0支持了.NET Core 和async/await。

    官网:http://www.quartz-scheduler.net/

    源码:https://github.com/quartznet/quartznet

    示例:https://www.quartz-scheduler.net/documentation/quartz-3.x/quick-start.html

    废话不多说直接上代码

    nuget引用Quartz 3.0

    1. 用代码调度定时任务
            public async static Task Init()
            {
                LogProvider.SetCurrentLogProvider(new CustomConsoleLogProvider());//Quartz提供了日志接口,这里可以自定义日志
                #region Scheduler 调度器
                StdSchedulerFactory factory = new StdSchedulerFactory();
                IScheduler scheduler = await factory.GetScheduler();//获取调度器
                scheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener());//添加调度器监听
                scheduler.ListenerManager.AddTriggerListener(new CustomTriggerListener());//添加时间策略监听
                scheduler.ListenerManager.AddJobListener(new CustomJobListener());//添加作业监听
                await scheduler.Start();//启动调度器
                #endregion
    
                #region 创建Job(作业)
                IJobDetail jobDetail = JobBuilder.Create<TestJob>()
                        .WithIdentity("testjob", "group1")//testjob- 作业名称  group1-分组名称
                        .WithDescription("This is TestJob jobDetail")//添加描述
                        .Build();
    
                jobDetail.JobDataMap.Add("key1", "value1");
                jobDetail.JobDataMap.Add("key2", "value2");
                jobDetail.JobDataMap.Add("key3", "value3");
                #endregion
    
                # region 创建时间策略 ITrigger
                ITrigger trigger = TriggerBuilder.Create()
                    .WithIdentity("testtrigger1", "group1")//testtrigger1- 时间策略名称  group1-分组名称
                    .StartAt(new DateTimeOffset(DateTime.Now.AddSeconds(10)))//10秒后启动
                    //.StartNow() //马上启动
                    .WithCronSchedule("5/10 * * * * ?")//每隔10秒执行一次
                    .WithDescription("This is testjob's Trigger")//添加描述
                    .Build();
                #endregion
    
                await scheduler.ScheduleJob(jobDetail,trigger);//按时间策略调度作业
            }
    
        public class CustomConsoleLogProvider : ILogProvider
        {
            public Logger GetLogger(string name)
            {
                return new Logger((level, func, exception, parameters) =>
                {
                    if (level >= LogLevel.Info && func != null)
                    {
                        Console.WriteLine($"[{ DateTime.Now.ToLongTimeString()}] [{ level}] { func()} {string.Join(";", parameters.Select(p => p == null ? " " : p.ToString()))}  自定义日志{name}");
                    }
                    return true;
                });
            }
    
            public IDisposable OpenMappedContext(string key, string value)
            {
                throw new NotImplementedException();
            }
    
            public IDisposable OpenNestedContext(string message)
            {
                throw new NotImplementedException();
            }
        }
    
    
        public class CustomSchedulerListener : ISchedulerListener
        {
            public async Task JobAdded(IJobDetail jobDetail, CancellationToken cancellationToken = default)
            {
                await Task.Run(() =>
                {
                    Console.WriteLine($" {DateTime.Now} {nameof(JobAdded)} {Thread.CurrentThread.ManagedThreadId} {jobDetail.Description}");
                });
            }
    
            public Task JobDeleted(JobKey jobKey, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task JobInterrupted(JobKey jobKey, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task JobPaused(JobKey jobKey, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task JobResumed(JobKey jobKey, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public async Task JobScheduled(ITrigger trigger, CancellationToken cancellationToken = default)
            {
                await Task.Run(() =>
                {
                    Console.WriteLine($" {DateTime.Now} {nameof(JobScheduled)} {Thread.CurrentThread.ManagedThreadId} {trigger.Description}");
                });
            }
    
            public Task JobsPaused(string jobGroup, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task JobsResumed(string jobGroup, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task JobUnscheduled(TriggerKey triggerKey, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task SchedulerError(string msg, SchedulerException cause, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task SchedulerInStandbyMode(CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task SchedulerShutdown(CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task SchedulerShuttingdown(CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public async Task SchedulerStarted(CancellationToken cancellationToken = default)
            {
                await Task.Run(() =>
                {
                    Console.WriteLine($" {DateTime.Now} {nameof(SchedulerStarted)} {Thread.CurrentThread.ManagedThreadId} {cancellationToken.WaitHandle.SafeWaitHandle.GetHashCode()}");
                });
            }
    
            public async Task SchedulerStarting(CancellationToken cancellationToken = default)
            {
                await Task.Run(() =>
                {
                    Console.WriteLine($" {DateTime.Now} {nameof(SchedulerStarting)} {Thread.CurrentThread.ManagedThreadId} {cancellationToken.WaitHandle.SafeWaitHandle.GetHashCode()}");
                });
            }
    
            public Task SchedulingDataCleared(CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task TriggerFinalized(ITrigger trigger, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task TriggerPaused(TriggerKey triggerKey, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task TriggerResumed(TriggerKey triggerKey, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task TriggersPaused(string triggerGroup, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
    
            public Task TriggersResumed(string triggerGroup, CancellationToken cancellationToken = default)
            {
                throw new NotImplementedException();
            }
        }
    
    
        public class CustomJobListener : IJobListener
        {
            public string Name => nameof(CustomJobListener);
    
            public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                await Task.Run(() => {
                    Console.WriteLine($"CustomJobListener JobExecutionVetoed {context.JobDetail.Description}");
                });
            }
    
            public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                await Task.Run(() => {
                    Console.WriteLine($"CustomJobListener JobToBeExecuted {context.JobDetail.Description}");
                });
            }
    
            public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
            {
                await Task.Run(() => {
                    Console.WriteLine($"CustomJobListener JobWasExecuted {context.JobDetail.Description}");
                });
            }
        }
    
    
        public class CustomTriggerListener : ITriggerListener
        {
            public string Name =>nameof(CustomTriggerListener);
    
            public async Task TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode, CancellationToken cancellationToken = default)
            {
                await Task.Run(() =>
                {
                    Console.WriteLine($"CustomTriggerListener TriggerComplete {trigger.Description}");
                });
            }
    
            public async Task TriggerFired(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default)
            {
                await Task.Run(() =>
                {
                    Console.WriteLine($"CustomTriggerListener TriggerFired {trigger.Description}");
                });
            }
    
            public async Task TriggerMisfired(ITrigger trigger, CancellationToken cancellationToken = default)
            {
                await Task.Run(() =>
                {
                    Console.WriteLine($"CustomTriggerListener TriggerMisfired {trigger.Description}");
                });
            }
    
            public async Task<bool> VetoJobExecution(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default)
            {
                await Task.Run(() =>
                {
                    Console.WriteLine($"CustomTriggerListener TriggerMisfired {trigger.Description}");
                });
                return false;//false才能继续执行
            }
        }
    
    
        public class TestJob : IJob
        {
            public async Task Execute(IJobExecutionContext context)
            {
                await Task.Run(() =>
                {
                    //需要执行的方法
                    Console.WriteLine($"{nameof(TestJob)} {Thread.CurrentThread.ManagedThreadId} {DateTime.Now}");
                });
            }
        }
    
    
    1. 结合Topshelf配置文件调度定时任务
                HostFactory.Run(x =>
                {
                    x.Service<ServiceRunner>();
                    x.EnablePauseAndContinue();
                });
    
    
        public sealed class ServiceRunner : ServiceControl, ServiceSuspend
        {
            private readonly IScheduler scheduler;
    
            public ServiceRunner()
            {
                scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
                scheduler.ListenerManager.AddSchedulerListener(new CustomSchedulerListener());//添加调度器监听
            }
    
            public bool Start(HostControl hostControl)
            {
                scheduler.Start();
                return true;
            }
    
            public bool Stop(HostControl hostControl)
            {
                scheduler.Shutdown(false);
                return true;
            }
    
            public bool Continue(HostControl hostControl)
            {
                scheduler.ResumeAll();
                return true;
            }
    
            public bool Pause(HostControl hostControl)
            {
                scheduler.PauseAll();
                return true;
            }
        }
    
    

    quartz.config

    # You can configure your scheduler in either <quartz> configuration section
    # or in quartz properties file
    # Configuration section has precedence
    
    quartz.scheduler.instanceName = QuartzTest
    
    # configure thread pool info
    quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
    quartz.threadPool.threadCount = 10
    quartz.threadPool.threadPriority = Normal
    
    # job initialization plugin handles our xml reading, without it defaults are used
    quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz.Plugins
    quartz.plugin.xml.fileNames = ~/quartz_jobs.xml
    
    # export this server to remoting context
    #quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
    #quartz.scheduler.exporter.port = 555
    #quartz.scheduler.exporter.bindName = QuartzScheduler
    #quartz.scheduler.exporter.channelType = tcp
    #quartz.scheduler.exporter.channelName = httpQuartz
    
    # 添加Job(作业)监听
    quartz.jobListener.CustomJobListener.type=TestConsole.QuartzHelper.CustomJobListener,TestConsole
    # 添加Trigger(时间策略)监听
    quartz.triggerListener.CustomTriggerListener.type=TestConsole.QuartzHelper.CustomTriggerListener,TestConsole
    

    quartz_jobs.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!-- This file contains job definitions in schema version 2.0 format -->
    
    <job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
    
      <processing-directives>
        <overwrite-existing-data>true</overwrite-existing-data>
      </processing-directives>
      <schedule> 
        <job>
          <name>TestJob</name>
          <group>TestJob</group>
          <description>TestJob</description>
          <job-type>TestConsole.QuartzHelper.TestJob,TestConsole</job-type>
          <durable>true</durable>
          <recover>false</recover>
        </job>
        <trigger>
          <cron>
            <name>TestJobTrigger</name>
            <group>TestJob</group>
            <job-name>TestJob</job-name>
            <job-group>TestJob</job-group>
            <start-time>2017-01-25T00:00:00+08:00</start-time>
            <cron-expression>0/10 * * * * ? </cron-expression>
          </cron>
        </trigger>
    
      </schedule>
    </job-scheduling-data>
    

    使用配置文件需要注意的是nuget需要引入Quartz.Plugins

    本文参考文档:
  • 相关阅读:
    Asp.net SignalR 实现服务端消息推送到Web端
    C#使用Quartz.NET详解
    Ubuntu 安装部署hugegraph
    chapter10.1、异常处理
    chapter13.2、SQLAlchemy
    chapter9.5、描述器
    chapter9.3、可调用对象,上下文管理
    chapter9.4、魔术方法反射
    chapter9.1、魔术方法
    chapter7.1、数据分发与队列queue
  • 原文地址:https://www.cnblogs.com/Dewumu/p/12918316.html
Copyright © 2020-2023  润新知