TopShelf.dll是一个可以把控制台应用程序转化为定时执行某一方法的程序,Visual Studio自带的定时程序不好调试,必须要安装到任务里面才可以调试,不太方便,使用TopShelf就可以直接运行调试,很方便。

Quartz.dll是一个任务调度框架,可以配置任意时间,单纯的Visual Studio自带的定时程序只能定时多少秒后执行,不能精确到时分秒。

首先加一个QuartzConfig来增加一个和TopShelf相对应的配置类

 private readonly IScheduler scheduler;
        public QuartzConfig()
        {
            // 从配置中读取计划执行策略
            //XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(new SimpleTypeLoadHelper());
            ISchedulerFactory sf = new StdSchedulerFactory();
            scheduler = sf.GetScheduler();
            //quartz_jobs.xml文件路径
            //processor.ProcessFileAndScheduleJobs("TopshelfConfig/quartz_jobs.xml", scheduler);
        }

        /// <summary>
        /// 启动quartz服务
        /// </summary>
        ///
        public void Start()
        {
            scheduler.Start();
                // 从配置中读取计划执行策略
                // 注意一定要在start后执行(除非不安装为windows服务),否则安装成windows服务无法启动(提示1053错误,服务没有及时响应启动或控制请求)
                XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(new SimpleTypeLoadHelper());
                processor.ProcessFileAndScheduleJobs("TopshelfConfig/quartz_jobs.xml", scheduler);
        }

        /// <summary>
        /// true:等待正在运行的计划任务执行完毕;
        /// false:强制关闭
        /// </summary>
        public void Stop()
        {
            scheduler.Shutdown(false);
        }

        /// <summary>
        /// 继续服务
        /// </summary>
        /// <returns></returns>
        public bool Continue()
        {
            try
            {
                scheduler.ResumeAll();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// 暂停服务
        /// </summary>
        /// <returns></returns>
        public bool Pause()
        {
            try
            {
                scheduler.PauseAll();
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
View Code

接下来增加quartz_jobs.config

<?xml version="1.0" encoding="utf-8" ?>
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData">
  <processing-directives>
    <overwrite-existing-data>true</overwrite-existing-data>
  </processing-directives>

  <schedule>
    <job>
      <!--job名称-->
      <name>XXXJob</name>
      <!--job分组-->
      <group>XXXGroup</group>
      <!--描述-->
      <description>描述</description>
      <!--job方法所在应用程序(类库)名.方法所在类,方法所在类-->
      <job-type>job方法所在应用程序(类库)名.方法所在类,方法所在类</job-type>
      <!--true:始终保留在Quartz的JobStore中;false:如果未关联trigger则移除-->
      <durable>true</durable>
      <recover>false</recover>
    </job>
    <!--复杂任务触发器-->
    <trigger>
      <cron>
        <!--trigger名称-->
        <name>XXXTrigger</name>
        <!--trigger分组-->
        <group>XXXTriggerGroup</group>
        <!--描述-->
        <description>描述</description>
        <!--绑定的job名称-->
        <job-name>XXXJob</job-name>
        <!--绑定的job组-->
        <job-group>XXXGroup</job-group>
        <!--当设置start-time属性的值早于当前时间时,任务启动会立即执行一次,然后根据cron表达式执行,否则只根据cron表达式的值来定时执行-->
        <!--<start-time>2020-07-31T00:00:00+08:00</start-time>-->
        <!--0 0 4 * * ? -->
        <!--每半小时执行一次-->
        <cron-expression>0 0/30 * * * ?</cron-expression>
      </cron>
    </trigger>
  </schedule>
</job-scheduling-data>
View Code

接下来就是将控制台转换为定时任务程序

HostFactory.Run(x =>
            {
                x.Service<QuartzConfig>(s =>
                {
                    s.ConstructUsing(name => new QuartzConfig());
                    s.WhenStarted(tc => tc.Start());
                    s.WhenStopped(tc => tc.Stop());
                    s.WhenPaused(tc => tc.Pause());
                    s.WhenContinued(tc => tc.Continue());
                });
                x.RunAsLocalSystem();
                x.SetDescription("安装为windows服务所显示的描述");
                x.SetDisplayName("安装为windows服务所显示的名称");
                x.SetServiceName("安装为windows服务的服务名称");
                x.EnableShutdown();
                x.EnablePauseAndContinue();
            });
        }
View Code

如果想安装为windows服务,到文件生成目录使用cmd命令执行一下:应用程序名称.exe install;卸载命令:应用程序名称.exe uninstall