这个应该是关于Quartz.Net使用的最后一篇文章了,之前的介绍都是基于Web的,这种实现任务调度的方式很少见,因为不管是MVC、WebApi还是WebService,它们都需要寄宿在IIS上运行,然而我们知道IIS是会定时回收进程池的,在一段时间内如果该站点没有收到任何请求,其就会进行回收,等到下次请求再自动启动。这样如果我们的任务需要在某个固定时间点执行就无法保障了。
因此,采用Windows Service来实现定时任务是更加合适的,它是由操作系统进行调度的,我们可以设置将服务设置为自启动,它将随着操作系统的启动而运行该进程。
新建一个Windows Service项目,其会为我们创建一个主入口
static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> static void Main() { try { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new Service1() }; ServiceBase.Run(ServicesToRun); } catch (Exception ex) { Console.WriteLine(ex.Message); throw; } } }
我们可以通过在Service1中来启动定时任务,通过log4net可以记录一些必要的日志
public partial class Service1 : ServiceBase { private Logger logger = new Logger(typeof(Service1)); public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { this.logger.Info("This is OnStart.."); IScheduler scheduler = await ScheduleManager.BuildScheduler(); //使用配置文件 XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(new SimpleTypeLoadHelper()); await processor.ProcessFileAndScheduleJobs("~/config/quartz_jobs.config", scheduler); } protected override void OnStop() { this.logger.Info("This is OnStop.."); } }
<?xml version="1.0" encoding="utf-8"?> <log4net> <!-- Define some output appenders --> <appender name="rollingAppender" type="log4net.Appender.RollingFileAppender"> <file value="log\log.txt" /> <!--追加日志内容--> <appendToFile value="true" /> <!--防止多线程时不能写Log,官方说线程非安全--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <!--可以为:Once|Size|Date|Composite--> <!--Composite为Size和Date的组合--> <rollingStyle value="Composite" /> <!--当备份文件时,为文件名加的后缀--> <datePattern value="yyyyMMdd.TXT" /> <!--日志最大个数,都是最新的--> <!--rollingStyle节点为Size时,只能有value个日志--> <!--rollingStyle节点为Composite时,每天有value个日志--> <maxSizeRollBackups value="20" /> <!--可用的单位:KB|MB|GB--> <maximumFileSize value="3MB" /> <!--置为true,当前最新日志文件名永远为file节中的名字--> <staticLogFileName value="true" /> <!--输出级别在INFO和ERROR之间的日志--> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="INFO" /> <param name="LevelMax" value="FATAL" /> </filter> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/> </layout> </appender> <!-- levels: OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL --> <root> <priority value="ALL"/> <level value="ALL"/> <appender-ref ref="rollingAppender" /> </root> </log4net>
public class Logger { static Logger() { XmlConfigurator.Configure(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config\\log4net.config"))); ILog Log = LogManager.GetLogger(typeof(Logger)); Log.Info("系统初始化Logger模块"); } private ILog loger = null; public Logger(Type type) { loger = LogManager.GetLogger(type); } /// <summary> /// Log4日志 /// </summary> /// <param name="msg"></param> /// <param name="ex"></param> public void Error(string msg = "出现异常", Exception ex = null) { loger.Error(msg, ex); } /// <summary> /// Log4日志 /// </summary> /// <param name="msg"></param> public void Warn(string msg) { loger.Warn(msg); } /// <summary> /// Log4日志 /// </summary> /// <param name="msg"></param> public void Info(string msg) { loger.Info(msg); } /// <summary> /// Log4日志 /// </summary> /// <param name="msg"></param> public void Debug(string msg) { loger.Debug(msg); } }
最后我们可以在Service1的界面上右键添加安装程序,来设置服务的一些信息。
接着通过编译完成后就可以通过下面的命令来安装或卸载服务了
C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil QuartzProject.WindowsService.exe C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil /u QuartzProject.WindowsService.exe