TopShelf.dll是一个可以把控制台应用程序转化为定时执行某一方法的程序,Visual Studio自带的定时程序不好调试,必须要安装到任务里面才可以调试,不太方便,使用TopShelf就可以直接运行调试,很方便。
Quartz.dll是一个任务调度框架,可以配置任意时间,单纯的Visual Studio自带的定时程序只能定时多少秒后执行,不能精确到时分秒。
首先加一个QuartzConfig来增加一个和TopShelf相对应的配置类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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; } }
接下来增加quartz_jobs.config
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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>
接下来就是将控制台转换为定时任务程序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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(); }); }
如果想安装为windows服务,到文件生成目录使用cmd命令执行一下:应用程序名称.exe install;卸载命令:应用程序名称.exe uninstall