• .Net Core 3.1 +Topshelf+Quartz创建Windows定时任务


    准备工作

    • 创建.net core 控制台应用程序,这里不做过多介绍
    • 添加TopShelf包:TopShelf;
    • 添加Quartz包:Quartz、Quartz.Plugins;
    • 添加依赖注入包:Microsoft.Extensions.DependencyInjection;
    • 添加读取配置文件包:Microsoft.Extensions.Configuration.Json;
    • 添加访问数据库包:Microsoft.EntityFrameworkCore;

    配置Quartz

    • 创建appsettings.json文件,右键文件属性,并更改属性为始终复制 内容
      {
      "quartz": {
          "scheduler": {
            "instanceName": "Job"
          },
          "threadPool": {
            "type": "Quartz.Simpl.SimpleThreadPool, Quartz",
            "threadPriority": "Normal",
            "threadCount": 10
          },
          "plugin": {
            "jobInitializer": {
              "type": "Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz.Plugins",
              "fileNames": "quartz_jobs.xml"
            }
          }
        }
      }
      

       

    • 创建QuartzOption 类
          public class QuartzOption
          {
              public QuartzOption(IConfiguration config)
              {
                  if (config == null)
                  {
                      throw new ArgumentNullException(nameof(config));
                  }
      
                  var section = config.GetSection("quartz");
                  section.Bind(this);
              }
      
              public Scheduler Scheduler { get; set; }
      
              public ThreadPool ThreadPool { get; set; }
      
              public Plugin Plugin { get; set; }
      
              public NameValueCollection ToProperties()
              {
                  var properties = new NameValueCollection
                  {
                      ["quartz.scheduler.instanceName"] = Scheduler?.InstanceName,
                      ["quartz.threadPool.type"] = ThreadPool?.Type,
                      ["quartz.threadPool.threadPriority"] = ThreadPool?.ThreadPriority,
                      ["quartz.threadPool.threadCount"] = ThreadPool?.ThreadCount.ToString(),
                      ["quartz.plugin.jobInitializer.type"] = Plugin?.JobInitializer?.Type,
                      ["quartz.plugin.jobInitializer.fileNames"] = Plugin?.JobInitializer?.FileNames
                  };
      
                  return properties;
              }
          }
      
          public class Scheduler
          {
              public string InstanceName { get; set; }
          }
      
          public class ThreadPool
          {
              public string Type { get; set; }
      
              public string ThreadPriority { get; set; }
      
              public int ThreadCount { get; set; }
          }
      
          public class Plugin
          {
              public JobInitializer JobInitializer { get; set; }
          }
      
          public class JobInitializer
          {
              public string Type { get; set; }
              public string FileNames { get; set; }
          }
      
      

        

    • 添加一个Job

      public class TestJob : IJob
          {
              private readonly IService _service;
      
              public SyncJob(IService service)
              {
                  _service = service;
              }
      
              public async Task Execute(IJobExecutionContext context)
              {
                  Log.Information("同步开始...");
                  _service.DoSomeThing();
              }
          }
      

        

    • 实现IJobFactory

      public class JobFactory : IJobFactory
          {
              protected readonly IServiceProvider Container;
      
              public JobFactory(IServiceProvider container)
              {
                  Container = container;
              }
      
              public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
              {
                  return Container.GetService(bundle.JobDetail.JobType) as IJob;
              }
      
              public void ReturnJob(IJob job)
              {
                  (job as IDisposable)?.Dispose();
              }
          }
      

        

    • 创建Quartz调度的配置文件 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>
            <!--TestJob测试 任务配置-->
            <job>
              <name>TestJob</name>
              <group>ServerGroup</group>
              <description>上传视频</description>
              <job-type>Server.TestJob, Server</job-type>
              <durable>true</durable>
              <recover>false</recover>
            </job>
            <trigger>
              <cron>
                <name>TestJobTrigger</name>
                <group>ServerGroup</group>
                <job-name>TestJob</job-name>
                <job-group>ServerGroup</job-group>
                <cron-expression>0/60 * * * * ?</cron-expression>
              </cron>
            </trigger>
      
            <!--TestJob2测试 任务配置-->
            <!--
          <job>
            <name>TestJob2</name>
            <group>Test</group>
            <description>TestJob2测试</description>
            <job-type>CoreSolution.Job.jobs.TestJob2,CoreSolution.Job</job-type>
            <durable>true</durable>
            <recover>false</recover>
          </job>
          <trigger>
            <cron>
              <name>TestJob2Trigger</name>
              <group>Test</group>
              <job-name>TestJob2</job-name>
              <job-group>Test</job-group>
              <cron-expression>0/30 * * * * ?</cron-expression>
              -->
            <!--30s执行一次-->
            <!--
            </cron>
          </trigger>-->
      
          </schedule>
        </job-scheduling-data>
      

        

    • 添加一个类,此类用户服务启动调用

    • public sealed class ServiceRunner : ServiceControl, ServiceSuspend
          {
              //调度器
              private readonly IScheduler scheduler;
              public ServiceRunner()
              {
      
                  scheduler = StdSchedulerFactory.GetDefaultScheduler().GetAwaiter().GetResult();
      
              }
              //开始
              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;
              }
          }
      

        

    • 配置TopShelf

      class Program
          {
              static void Main(string[] args)
              {
                  var rc = HostFactory.Run(x =>
                  {
                     x.Service<ServiceRunner>(s => {
                          s.ConstructUsing(name => new ServiceRunner());
                          s.WhenStarted((tc, hc) => tc.Start(hc));
                          s.WhenStopped((tc, hc) => tc.Stop(hc));
                          s.WhenContinued((tc, hc) => tc.Continue(hc));
                          s.WhenPaused((tc, hc) => tc.Pause(hc));
                      });
      
                      x.RunAsLocalService();
                      x.StartAutomaticallyDelayed();
                      x.RunAsLocalSystem();
      
                      x.SetDescription("测试后台服务");
                      x.SetDisplayName("TestServer");
                      x.SetServiceName("TestServer");
                      x.EnablePauseAndContinue();
                  });
                  var exitCode = (int)Convert.ChangeType(rc, rc.GetTypeCode());
                  Environment.ExitCode = exitCode;
              }
          }
      

        

  • 相关阅读:
    我的书单
    算法面试 字符串全排列
    各种算法面试简介--面试用一句话陈述
    逻辑回归 面试
    EM算法 小结
    python实现 单链表的翻转
    Transformer模型总结
    逻辑回归原理 面试 Logistic Regression
    XGBoost的优点
    python-解决pip安装速度慢的问题--豆瓣镜像
  • 原文地址:https://www.cnblogs.com/DavidAi/p/13685431.html
Copyright © 2020-2023  润新知