直接贴代码了:

首先我们可以把所有的 Job 放到一个单独的 DLL 中,好处是可以共享这些业务 Job。比如我们新建一个 QuartzNetDemo.WinService.Jobs 的类库。

然后,我们再先定义一个 WriteTextToFileJob 的任务:

  1. public class WriteTextToFileJob : IJob
  2. {
  3. // Fields
  4. private static readonly string TypeName = typeof(WriteTextToFileJob).FullName;
  5.  
  6. // Methods
  7. public virtual void Execute(IJobExecutionContext context)
  8. {
  9. FileUtil.AppendFormat("=================================任务开始:{0}=================================", new object[] { TypeName });
  10. FileUtil.AppendFormat("当前时间:{0},正在运行...", new object[] { DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") });
  11. if (context.JobDetail.JobDataMap.ContainsKey("UserName"))
  12. {
  13. string str = context.JobDetail.JobDataMap.GetString("UserName");
  14. FileUtil.AppendFormat("当前时间:{0},接受到参数 \"{1}\" 的值等于 {2}", new object[] { DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "UserName", str });
  15. }
  16. if (context.JobDetail.JobDataMap.ContainsKey("Msg"))
  17. {
  18. string str2 = context.JobDetail.JobDataMap.GetString("Msg");
  19. FileUtil.AppendFormat("当前时间:{0},接受到参数 \"{1}\" 的值等于 {2}", new object[] { DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), "Msg", str2 });
  20. }
  21. FileUtil.AppendFormat("当前时间:{0},准备暂停 {1} 秒钟...", new object[] { DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), });
  22. Thread.Sleep(TimeSpan.FromSeconds(5.0));
  23. FileUtil.AppendFormat("当前时间:{0},已经运行完毕!", new object[] { DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") });
  24. FileUtil.AppendFormat("=================================任务结束:{0}=================================", new object[] { TypeName });
  25. }
  26. }

App.config

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3. <!-- 注意:App.config 文件更改后,无须重新安装 Windows Services,只需要重启就可以了 -->
  4. <configSections>
  5. <!-- 注册 Quartz 节点 -->
  6. <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  7. <!-- 注册 log4net -->
  8. <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  9. </configSections>
  10. <!-- 配置 log4net -->
  11. <log4net configSource="log4net.config" />
  12. <appSettings>
  13. <!-- 下面是配置 Windows 服务的相关参数 -->
  14. <add key="quartz.server.serviceName" value="QuartzNetDemoWinService" />
  15. <add key="quartz.server.serviceDisplayName" value="QuartzNetDemoWinService" />
  16. <add key="quartz.server.serviceDescription" value="负责项目的定时调度任务" />
  17. </appSettings>
  18. <!-- Quartz 配置 -->
  19. <quartz>
  20. <!-- 基本参数配置 -->
  21. <add key="quartz.scheduler.instanceName" value="QuartzNetDemo.WinService" />
  22. <add key="quartz.scheduler.instanceId" value="AUTO" />
  23. <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
  24. <add key="quartz.threadPool.threadCount" value="" />
  25. <add key="quartz.threadPool.threadPriority" value="Normal" />
  26. <!-- 下面是配置把 Quartz 相关的任务和触发器保存在数据库中 -->
  27. <add key="quartz.jobStore.useProperties" value="true" />
  28. <add key="quartz.jobStore.clustered" value="true" />
  29. <add key="quartz.jobStore.misfireThreshold" value="" />
  30. <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
  31. <add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
  32. <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz" />
  33. <add key="quartz.jobStore.dataSource" value="myDS" />
  34. <add key="quartz.dataSource.myDS.connectionString" value="Data Source=.;Initial Catalog=TestDB;User ID=sa;Password=123456;" />
  35. <add key="quartz.dataSource.myDS.provider" value="SqlServer-20" />
  36. <!-- 下面是配置可以远程访问
  37. <add key="quartz.scheduler.exporter.type" value="Quartz.Simpl.RemotingSchedulerExporter, Quartz"/>
  38. <add key="quartz.scheduler.exporter.port" value=""/>
  39. <add key="quartz.scheduler.exporter.bindName" value="QuartzScheduler"/>
  40. <add key="quartz.scheduler.exporter.channelType" value="tcp"/>
  41. <add key="quartz.scheduler.exporter.channelName" value="httpQuartz"/>
  42. <add key="quartz.scheduler.exporter.rejectRemoteRequests" value="true"/>
  43. -->
  44. <!-- 下面是 XML 注册任务(是否可以不配置) -->
  45. <add key="quartz.plugin.xml.type" value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz" />
  46. <add key="quartz.plugin.xml.fileNames" value="~/quartz_jobs.xml" />
  47. <!-- 下面是触发器历史记录插件 -->
  48. <add key="quartz.plugin.triggHistory.type" value="Quartz.Plugin.History.LoggingJobHistoryPlugin" />
  49. <!-- 下面是 XML 任务初始化 - 单位为秒 -->
  50. <add key="quartz.plugin.jobInitializer.type" value="Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin" />
  51. <add key="quartz.plugin.jobInitializer.fileNames" value="quartz_jobs.xml" />
  52. <add key="quartz.plugin.jobInitializer.failOnFileNotFound" value="true" />
  53. <add key="quartz.plugin.jobInitializer.scanInterval" value="" />
  54. </quartz>
  55. <startup>
  56. <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  57. </startup>
  58. </configuration>

quartz_jobs.xml

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. version="2.0">
  5.  
  6. <processing-directives>
  7. <overwrite-existing-data>true</overwrite-existing-data>
  8. </processing-directives>
  9.  
  10. <schedule>
  11.  
  12. <job>
  13. <name>WriteTextToFileJob</name>
  14. <group>jobGroup1</group>
  15. <description>jobDesciption1</description>
  16. <job-type>QuartzNetDemo.WinService.Jobs.WriteTextToFileJob, QuartzNetDemo.WinService.Jobs</job-type>
  17. <durable>true</durable>
  18. <recover>false</recover>
  19. <job-data-map>
  20. <entry>
  21. <key>UserName</key>
  22. <value>周星驰</value>
  23. </entry>
  24. <entry>
  25. <key>Msg</key>
  26. <value>Hello world,欢迎使用 Quartz.net 调度组件</value>
  27. </entry>
  28. </job-data-map>
  29. </job>
  30.  
  31. <trigger>
  32. <simple>
  33. <name>WriteTextToFileJobTrigger</name>
  34. <group>triggerGroup1</group>
  35. <description>SimpleTriggerDescription</description>
  36. <job-name>WriteTextToFileJob</job-name>
  37. <job-group>jobGroup1</job-group>
  38. <start-time>--28T18::.0Z</start-time>
  39. <end-time>--04T18::.0Z</end-time>
  40. <misfire-instruction>SmartPolicy</misfire-instruction>
  41. <repeat-count></repeat-count>
  42. <repeat-interval></repeat-interval>
  43. </simple>
  44. </trigger>
  45.  
  46. </schedule>
  47.  
  48. </job-scheduling-data>

log4net.config

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <log4net>
  3. <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
  4. <param name="File" value="Log\log_" />
  5. <param name="AppendToFile" value="true" />
  6. <!-- <datePattern value="yyyy\\yyyyMM\\yyyyMMdd'.txt'"/> 这句是按照年月文件夹分类 -->
  7. <param name="DatePattern" value="yyyy-MM-dd_HH&quot;.log&quot;" />
  8. <param name="RollingStyle" value="Date" />
  9. <param name="StaticLogFileName" value="false" />
  10. <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  11. <layout type="log4net.Layout.PatternLayout">
  12. <param name="ConversionPattern" value="%d [%t] %-5p %x %m %n" />
  13. <!--每条日志末尾的文字说明-->
  14. <!--输出格式-->
  15. <!--样例:-- ::, [] INFO Fujica.PackingPlatform.WebUI.MainClass [(null)] - info-->
  16. <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n出错类: %file 在第 %line 行 %n描述:%message%newline %n"/>
  17. </layout>
  18. <filter type="log4net.Filter.LevelRangeFilter">
  19. <param name="LevelMin" value="INFO" />
  20. <param name="LevelMax" value="FATAL" />
  21. </filter>
  22. </appender>
  23. <!-- Admin 访问信息 -->
  24. <appender name="AdminLogFileAppender" type="log4net.Appender.RollingFileAppender">
  25. <param name="File" value="Log\admin_log_" />
  26. <param name="AppendToFile" value="true" />
  27. <!-- <datePattern value="yyyy\\yyyyMM\\yyyyMMdd'.txt'"/> 这句是按照年月文件夹分类 -->
  28. <param name="DatePattern" value="yyyy-MM-dd&quot;.log&quot;" />
  29. <param name="RollingStyle" value="Date" />
  30. <param name="StaticLogFileName" value="false" />
  31. <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  32. <layout type="log4net.Layout.PatternLayout">
  33. <param name="ConversionPattern" value="%d [%t] %-5p %x %m %n" />
  34. <!--每条日志末尾的文字说明-->
  35. <!--输出格式-->
  36. <!--样例:-- ::, [] INFO Fujica.PackingPlatform.WebUI.MainClass [(null)] - info-->
  37. <conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别: %-5level %n出错类: %file 在第 %line 行 %n描述:%message%newline %n"/>
  38. </layout>
  39. <filter type="log4net.Filter.LevelRangeFilter">
  40. <param name="LevelMin" value="INFO" />
  41. <param name="LevelMax" value="FATAL" />
  42. </filter>
  43. </appender>
  44. <logger name="adminLogger" additivity="false">
  45. <level value="ALL" />
  46. <appender-ref ref="AdminLogFileAppender" />
  47. </logger>
  48. <root>
  49. <level value="ALL" />
  50. <appender-ref ref="AdminLogFileAppender" />
  51. <appender-ref ref="LogFileAppender" />
  52. </root>
  53. </log4net>

SchedulerServer.cs

  1. using log4net.Config;
  2. using Quartz.Impl;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7.  
  8. namespace QuartzNetDemo.WinService
  9. {
  10. public class SchedulerServer
  11. {
  12. // Fields
  13. private readonly StdSchedulerFactory _schedulerFactory = new StdSchedulerFactory();
  14.  
  15. // Methods
  16. public void Start()
  17. {
  18. Console.WriteLine("Starting scheduler...");
  19. XmlConfigurator.Configure();
  20. this._schedulerFactory.GetScheduler().Start();
  21. }
  22.  
  23. public void Stop()
  24. {
  25. if (this._schedulerFactory != null) this._schedulerFactory.GetScheduler().Shutdown(false);
  26. }
  27. }
  28. }

Configuration.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Configuration;
  5. using System.Linq;
  6. using System.Text;
  7.  
  8. namespace QuartzNetDemo.WinService
  9. {
  10. public class Configuration
  11. {
  12. // Fields
  13. private static readonly NameValueCollection configuration = ((NameValueCollection) ConfigurationManager.GetSection("appSettings"));
  14. private const string DefaultServiceDescription = "负责项目的定时调度任务";
  15. private const string DefaultServiceDisplayName = "QuartzNetDemoWinService";
  16. private const string DefaultServiceName = "QuartzNetDemoWinService";
  17. private const string KeyServiceDescription = "quartz.server.serviceDescription";
  18. private const string KeyServiceDisplayName = "quartz.server.serviceDisplayName";
  19. private const string KeyServiceName = "quartz.server.serviceName";
  20. private const string PrefixServerConfiguration = "quartz.server";
  21.  
  22. // Methods
  23. private static string GetConfigurationOrDefault(string configurationKey, string defaultValue)
  24. {
  25. string retValue = null;
  26. if (configuration != null) retValue = configuration[configurationKey];
  27. if (retValue == null || retValue.Trim().Length == ) retValue = defaultValue;
  28. return retValue;
  29. }
  30.  
  31. // Properties
  32. public static string ServiceDescription
  33. {
  34. get
  35. {
  36. return GetConfigurationOrDefault(KeyServiceDescription, DefaultServiceDescription);
  37. }
  38. }
  39.  
  40. public static string ServiceDisplayName
  41. {
  42. get
  43. {
  44. return GetConfigurationOrDefault(KeyServiceDisplayName, DefaultServiceDisplayName);
  45. }
  46. }
  47.  
  48. public static string ServiceName
  49. {
  50. get
  51. {
  52. return GetConfigurationOrDefault(KeyServiceName, DefaultServiceName);
  53. }
  54. }
  55. }
  56. }

Program.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Topshelf;
  6. using Topshelf.HostConfigurators;
  7. using Topshelf.ServiceConfigurators;
  8.  
  9. namespace QuartzNetDemo.WinService
  10. {
  11. class Program
  12. {
  13. static void Main(string[] args)
  14. {
  15. HostFactory.Run(delegate(HostConfigurator x)
  16. {
  17. x.Service<SchedulerServer>( (ServiceConfigurator<SchedulerServer> s) =>
  18. {
  19. s.ConstructUsing(name => new SchedulerServer());
  20. s.WhenStarted<SchedulerServer>(tc => tc.Start());
  21. s.WhenStopped<SchedulerServer>(tc => tc.Stop());
  22. });
  23. x.RunAsLocalSystem();
  24. x.SetDescription(Configuration.ServiceDescription);
  25. x.SetDisplayName(Configuration.ServiceDisplayName);
  26. x.SetServiceName(Configuration.ServiceName);
  27. });
  28. }
  29. }
  30. }

Quartz.NET 官方的 tables_sqlServer.sql

  1. -- this script is for SQL Server and Azure SQL
  2.  
  3. USE [enter_db_name_here]
  4. GO
  5.  
  6. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
  7. ALTER TABLE [dbo].[QRTZ_TRIGGERS] DROP CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS
  8. GO
  9.  
  10. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
  11. ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS
  12. GO
  13.  
  14. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
  15. ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS
  16. GO
  17.  
  18. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
  19. ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS
  20. GO
  21.  
  22. IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_QRTZ_JOB_LISTENERS_QRTZ_JOB_DETAILS]') AND parent_object_id = OBJECT_ID(N'[dbo].[QRTZ_JOB_LISTENERS]'))
  23. ALTER TABLE [dbo].[QRTZ_JOB_LISTENERS] DROP CONSTRAINT [FK_QRTZ_JOB_LISTENERS_QRTZ_JOB_DETAILS]
  24.  
  25. IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_QRTZ_TRIGGER_LISTENERS_QRTZ_TRIGGERS]') AND parent_object_id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGER_LISTENERS]'))
  26. ALTER TABLE [dbo].[QRTZ_TRIGGER_LISTENERS] DROP CONSTRAINT [FK_QRTZ_TRIGGER_LISTENERS_QRTZ_TRIGGERS]
  27.  
  28. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  29. DROP TABLE [dbo].[QRTZ_CALENDARS]
  30. GO
  31.  
  32. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  33. DROP TABLE [dbo].[QRTZ_CRON_TRIGGERS]
  34. GO
  35.  
  36. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  37. DROP TABLE [dbo].[QRTZ_BLOB_TRIGGERS]
  38. GO
  39.  
  40. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  41. DROP TABLE [dbo].[QRTZ_FIRED_TRIGGERS]
  42. GO
  43.  
  44. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  45. DROP TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS]
  46. GO
  47.  
  48. IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[QRTZ_JOB_LISTENERS]') AND type in (N'U'))
  49. DROP TABLE [dbo].[QRTZ_JOB_LISTENERS]
  50.  
  51. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  52. DROP TABLE [dbo].[QRTZ_SCHEDULER_STATE]
  53. GO
  54.  
  55. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  56. DROP TABLE [dbo].[QRTZ_LOCKS]
  57. GO
  58. IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGER_LISTENERS]') AND type in (N'U'))
  59. DROP TABLE [dbo].[QRTZ_TRIGGER_LISTENERS]
  60.  
  61. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  62. DROP TABLE [dbo].[QRTZ_JOB_DETAILS]
  63. GO
  64.  
  65. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  66. DROP TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS]
  67. GO
  68.  
  69. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  70. DROP TABLE [dbo].QRTZ_SIMPROP_TRIGGERS
  71. GO
  72.  
  73. IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
  74. DROP TABLE [dbo].[QRTZ_TRIGGERS]
  75. GO
  76.  
  77. CREATE TABLE [dbo].[QRTZ_CALENDARS] (
  78. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  79. [CALENDAR_NAME] [NVARCHAR] (200) NOT NULL ,
  80. [CALENDAR] [VARBINARY](MAX) NOT NULL
  81. )
  82. GO
  83.  
  84. CREATE TABLE [dbo].[QRTZ_CRON_TRIGGERS] (
  85. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  86. [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
  87. [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
  88. [CRON_EXPRESSION] [NVARCHAR] (120) NOT NULL ,
  89. [TIME_ZONE_ID] [NVARCHAR] (80)
  90. )
  91. GO
  92.  
  93. CREATE TABLE [dbo].[QRTZ_FIRED_TRIGGERS] (
  94. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  95. [ENTRY_ID] [NVARCHAR] (140) NOT NULL ,
  96. [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
  97. [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
  98. [INSTANCE_NAME] [NVARCHAR] (200) NOT NULL ,
  99. [FIRED_TIME] [BIGINT] NOT NULL ,
  100. [SCHED_TIME] [BIGINT] NOT NULL ,
  101. [PRIORITY] [INTEGER] NOT NULL ,
  102. [STATE] [NVARCHAR] (16) NOT NULL,
  103. [JOB_NAME] [NVARCHAR] (150) NULL ,
  104. [JOB_GROUP] [NVARCHAR] (150) NULL ,
  105. [IS_NONCONCURRENT] BIT NULL ,
  106. [REQUESTS_RECOVERY] BIT NULL
  107. )
  108. GO
  109.  
  110. CREATE TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] (
  111. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  112. [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL
  113. )
  114. GO
  115.  
  116. CREATE TABLE [dbo].[QRTZ_SCHEDULER_STATE] (
  117. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  118. [INSTANCE_NAME] [NVARCHAR] (200) NOT NULL ,
  119. [LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,
  120. [CHECKIN_INTERVAL] [BIGINT] NOT NULL
  121. )
  122. GO
  123.  
  124. CREATE TABLE [dbo].[QRTZ_LOCKS] (
  125. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  126. [LOCK_NAME] [NVARCHAR] (40) NOT NULL
  127. )
  128. GO
  129.  
  130. CREATE TABLE [dbo].[QRTZ_JOB_DETAILS] (
  131. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  132. [JOB_NAME] [NVARCHAR] (150) NOT NULL ,
  133. [JOB_GROUP] [NVARCHAR] (150) NOT NULL ,
  134. [DESCRIPTION] [NVARCHAR] (250) NULL ,
  135. [JOB_CLASS_NAME] [NVARCHAR] (250) NOT NULL ,
  136. [IS_DURABLE] BIT NOT NULL ,
  137. [IS_NONCONCURRENT] BIT NOT NULL ,
  138. [IS_UPDATE_DATA] BIT NOT NULL ,
  139. [REQUESTS_RECOVERY] BIT NOT NULL ,
  140. [JOB_DATA] [VARBINARY](MAX) NULL
  141. )
  142. GO
  143.  
  144. CREATE TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] (
  145. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  146. [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
  147. [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
  148. [REPEAT_COUNT] [INTEGER] NOT NULL ,
  149. [REPEAT_INTERVAL] [BIGINT] NOT NULL ,
  150. [TIMES_TRIGGERED] [INTEGER] NOT NULL
  151. )
  152. GO
  153.  
  154. CREATE TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] (
  155. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  156. [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
  157. [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
  158. [STR_PROP_1] [NVARCHAR] (512) NULL,
  159. [STR_PROP_2] [NVARCHAR] (512) NULL,
  160. [STR_PROP_3] [NVARCHAR] (512) NULL,
  161. [INT_PROP_1] [INT] NULL,
  162. [INT_PROP_2] [INT] NULL,
  163. [LONG_PROP_1] [BIGINT] NULL,
  164. [LONG_PROP_2] [BIGINT] NULL,
  165. [DEC_PROP_1] [NUMERIC] (13,4) NULL,
  166. [DEC_PROP_2] [NUMERIC] (13,4) NULL,
  167. [BOOL_PROP_1] BIT NULL,
  168. [BOOL_PROP_2] BIT NULL,
  169. [TIME_ZONE_ID] [NVARCHAR] (80) NULL
  170. )
  171. GO
  172.  
  173. CREATE TABLE [dbo].[QRTZ_BLOB_TRIGGERS] (
  174. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  175. [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
  176. [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
  177. [BLOB_DATA] [VARBINARY](MAX) NULL
  178. )
  179. GO
  180.  
  181. CREATE TABLE [dbo].[QRTZ_TRIGGERS] (
  182. [SCHED_NAME] [NVARCHAR] (120) NOT NULL ,
  183. [TRIGGER_NAME] [NVARCHAR] (150) NOT NULL ,
  184. [TRIGGER_GROUP] [NVARCHAR] (150) NOT NULL ,
  185. [JOB_NAME] [NVARCHAR] (150) NOT NULL ,
  186. [JOB_GROUP] [NVARCHAR] (150) NOT NULL ,
  187. [DESCRIPTION] [NVARCHAR] (250) NULL ,
  188. [NEXT_FIRE_TIME] [BIGINT] NULL ,
  189. [PREV_FIRE_TIME] [BIGINT] NULL ,
  190. [PRIORITY] [INTEGER] NULL ,
  191. [TRIGGER_STATE] [NVARCHAR] (16) NOT NULL ,
  192. [TRIGGER_TYPE] [NVARCHAR] (8) NOT NULL ,
  193. [START_TIME] [BIGINT] NOT NULL ,
  194. [END_TIME] [BIGINT] NULL ,
  195. [CALENDAR_NAME] [NVARCHAR] (200) NULL ,
  196. [MISFIRE_INSTR] [INTEGER] NULL ,
  197. [JOB_DATA] [VARBINARY](MAX) NULL
  198. )
  199. GO
  200.  
  201. ALTER TABLE [dbo].[QRTZ_CALENDARS] WITH NOCHECK ADD
  202. CONSTRAINT [PK_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED
  203. (
  204. [SCHED_NAME],
  205. [CALENDAR_NAME]
  206. )
  207. GO
  208.  
  209. ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD
  210. CONSTRAINT [PK_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED
  211. (
  212. [SCHED_NAME],
  213. [TRIGGER_NAME],
  214. [TRIGGER_GROUP]
  215. )
  216. GO
  217.  
  218. ALTER TABLE [dbo].[QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD
  219. CONSTRAINT [PK_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED
  220. (
  221. [SCHED_NAME],
  222. [ENTRY_ID]
  223. )
  224. GO
  225.  
  226. ALTER TABLE [dbo].[QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD
  227. CONSTRAINT [PK_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED
  228. (
  229. [SCHED_NAME],
  230. [TRIGGER_GROUP]
  231. )
  232. GO
  233.  
  234. ALTER TABLE [dbo].[QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD
  235. CONSTRAINT [PK_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED
  236. (
  237. [SCHED_NAME],
  238. [INSTANCE_NAME]
  239. )
  240. GO
  241.  
  242. ALTER TABLE [dbo].[QRTZ_LOCKS] WITH NOCHECK ADD
  243. CONSTRAINT [PK_QRTZ_LOCKS] PRIMARY KEY CLUSTERED
  244. (
  245. [SCHED_NAME],
  246. [LOCK_NAME]
  247. )
  248. GO
  249.  
  250. ALTER TABLE [dbo].[QRTZ_JOB_DETAILS] WITH NOCHECK ADD
  251. CONSTRAINT [PK_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED
  252. (
  253. [SCHED_NAME],
  254. [JOB_NAME],
  255. [JOB_GROUP]
  256. )
  257. GO
  258.  
  259. ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD
  260. CONSTRAINT [PK_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED
  261. (
  262. [SCHED_NAME],
  263. [TRIGGER_NAME],
  264. [TRIGGER_GROUP]
  265. )
  266. GO
  267.  
  268. ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD
  269. CONSTRAINT [PK_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED
  270. (
  271. [SCHED_NAME],
  272. [TRIGGER_NAME],
  273. [TRIGGER_GROUP]
  274. )
  275. GO
  276.  
  277. ALTER TABLE [dbo].[QRTZ_TRIGGERS] WITH NOCHECK ADD
  278. CONSTRAINT [PK_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED
  279. (
  280. [SCHED_NAME],
  281. [TRIGGER_NAME],
  282. [TRIGGER_GROUP]
  283. )
  284. GO
  285.  
  286. ALTER TABLE [dbo].QRTZ_BLOB_TRIGGERS WITH NOCHECK ADD
  287. CONSTRAINT [PK_QRTZ_BLOB_TRIGGERS] PRIMARY KEY CLUSTERED
  288. (
  289. [SCHED_NAME],
  290. [TRIGGER_NAME],
  291. [TRIGGER_GROUP]
  292. )
  293. GO
  294.  
  295. ALTER TABLE [dbo].[QRTZ_CRON_TRIGGERS] ADD
  296. CONSTRAINT [FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
  297. (
  298. [SCHED_NAME],
  299. [TRIGGER_NAME],
  300. [TRIGGER_GROUP]
  301. ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
  302. [SCHED_NAME],
  303. [TRIGGER_NAME],
  304. [TRIGGER_GROUP]
  305. ) ON DELETE CASCADE
  306. GO
  307.  
  308. ALTER TABLE [dbo].[QRTZ_SIMPLE_TRIGGERS] ADD
  309. CONSTRAINT [FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
  310. (
  311. [SCHED_NAME],
  312. [TRIGGER_NAME],
  313. [TRIGGER_GROUP]
  314. ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
  315. [SCHED_NAME],
  316. [TRIGGER_NAME],
  317. [TRIGGER_GROUP]
  318. ) ON DELETE CASCADE
  319. GO
  320.  
  321. ALTER TABLE [dbo].[QRTZ_SIMPROP_TRIGGERS] ADD
  322. CONSTRAINT [FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS] FOREIGN KEY
  323. (
  324. [SCHED_NAME],
  325. [TRIGGER_NAME],
  326. [TRIGGER_GROUP]
  327. ) REFERENCES [dbo].[QRTZ_TRIGGERS] (
  328. [SCHED_NAME],
  329. [TRIGGER_NAME],
  330. [TRIGGER_GROUP]
  331. ) ON DELETE CASCADE
  332. GO
  333.  
  334. ALTER TABLE [dbo].[QRTZ_TRIGGERS] ADD
  335. CONSTRAINT [FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS] FOREIGN KEY
  336. (
  337. [SCHED_NAME],
  338. [JOB_NAME],
  339. [JOB_GROUP]
  340. ) REFERENCES [dbo].[QRTZ_JOB_DETAILS] (
  341. [SCHED_NAME],
  342. [JOB_NAME],
  343. [JOB_GROUP]
  344. )
  345. GO
  346.  
  347. CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP)
  348. CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP)
  349. CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME)
  350. CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP)
  351. CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE)
  352. CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE)
  353. CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE)
  354. CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME)
  355. CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME)
  356. CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME)
  357. CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE)
  358. CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE)
  359.  
  360. CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME)
  361. CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY)
  362. CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP)
  363. CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP)
  364. CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
  365. CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP)
  366. GO

运行后生成的日志比如:admin_log_2018-09-21.log

  1. 记录时间:2018-09-21 15:52:22,249
  2. 线程ID:[QuartzNetDemo.WinService_Worker-2]
  3. 日志级别: INFO
  4. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  5. 描述:=================================任务开始:QuartzNetDemo.WinService.Jobs.WriteTextToFileJob=================================
  6.  
  7. 记录时间:2018-09-21 15:52:22,295
  8. 线程ID:[QuartzNetDemo.WinService_Worker-2]
  9. 日志级别: INFO
  10. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  11. 描述:当前时间:2018-09-21 15:52:22,正在运行...
  12.  
  13. 记录时间:2018-09-21 15:52:22,296
  14. 线程ID:[QuartzNetDemo.WinService_Worker-2]
  15. 日志级别: INFO
  16. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  17. 描述:当前时间:2018-09-21 15:52:22,接受到参数 "UserName" 的值等于 周星驰
  18.  
  19. 记录时间:2018-09-21 15:52:22,296
  20. 线程ID:[QuartzNetDemo.WinService_Worker-2]
  21. 日志级别: INFO
  22. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  23. 描述:当前时间:2018-09-21 15:52:22,接受到参数 "Msg" 的值等于 Hello world,欢迎使用 Quartz.net 调度组件
  24.  
  25. 记录时间:2018-09-21 15:52:22,297
  26. 线程ID:[QuartzNetDemo.WinService_Worker-2]
  27. 日志级别: INFO
  28. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  29. 描述:当前时间:2018-09-21 15:52:22,准备暂停 5 秒钟...
  30.  
  31. 记录时间:2018-09-21 15:52:25,192
  32. 线程ID:[QuartzNetDemo.WinService_Worker-3]
  33. 日志级别: INFO
  34. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  35. 描述:=================================任务开始:QuartzNetDemo.WinService.Jobs.WriteTextToFileJob=================================
  36.  
  37. 记录时间:2018-09-21 15:52:25,193
  38. 线程ID:[QuartzNetDemo.WinService_Worker-3]
  39. 日志级别: INFO
  40. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  41. 描述:当前时间:2018-09-21 15:52:25,正在运行...
  42.  
  43. 记录时间:2018-09-21 15:52:25,196
  44. 线程ID:[QuartzNetDemo.WinService_Worker-3]
  45. 日志级别: INFO
  46. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  47. 描述:当前时间:2018-09-21 15:52:25,接受到参数 "UserName" 的值等于 周星驰
  48.  
  49. 记录时间:2018-09-21 15:52:25,197
  50. 线程ID:[QuartzNetDemo.WinService_Worker-3]
  51. 日志级别: INFO
  52. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  53. 描述:当前时间:2018-09-21 15:52:25,接受到参数 "Msg" 的值等于 Hello world,欢迎使用 Quartz.net 调度组件
  54.  
  55. 记录时间:2018-09-21 15:52:25,198
  56. 线程ID:[QuartzNetDemo.WinService_Worker-3]
  57. 日志级别: INFO
  58. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  59. 描述:当前时间:2018-09-21 15:52:25,准备暂停 5 秒钟...
  60.  
  61. 记录时间:2018-09-21 15:52:27,298
  62. 线程ID:[QuartzNetDemo.WinService_Worker-2]
  63. 日志级别: INFO
  64. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  65. 描述:当前时间:2018-09-21 15:52:27,已经运行完毕!
  66.  
  67. 记录时间:2018-09-21 15:52:27,300
  68. 线程ID:[QuartzNetDemo.WinService_Worker-2]
  69. 日志级别: INFO
  70. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  71. 描述:=================================任务结束:QuartzNetDemo.WinService.Jobs.WriteTextToFileJob=================================
  72.  
  73. 记录时间:2018-09-21 15:52:28,191
  74. 线程ID:[QuartzNetDemo.WinService_Worker-4]
  75. 日志级别: INFO
  76. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  77. 描述:=================================任务开始:QuartzNetDemo.WinService.Jobs.WriteTextToFileJob=================================
  78.  
  79. 记录时间:2018-09-21 15:52:28,193
  80. 线程ID:[QuartzNetDemo.WinService_Worker-4]
  81. 日志级别: INFO
  82. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  83. 描述:当前时间:2018-09-21 15:52:28,正在运行...
  84.  
  85. 记录时间:2018-09-21 15:52:28,194
  86. 线程ID:[QuartzNetDemo.WinService_Worker-4]
  87. 日志级别: INFO
  88. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  89. 描述:当前时间:2018-09-21 15:52:28,接受到参数 "UserName" 的值等于 周星驰
  90.  
  91. 记录时间:2018-09-21 15:52:28,195
  92. 线程ID:[QuartzNetDemo.WinService_Worker-4]
  93. 日志级别: INFO
  94. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  95. 描述:当前时间:2018-09-21 15:52:28,接受到参数 "Msg" 的值等于 Hello world,欢迎使用 Quartz.net 调度组件
  96.  
  97. 记录时间:2018-09-21 15:52:28,197
  98. 线程ID:[QuartzNetDemo.WinService_Worker-4]
  99. 日志级别: INFO
  100. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  101. 描述:当前时间:2018-09-21 15:52:28,准备暂停 5 秒钟...
  102.  
  103. 记录时间:2018-09-21 15:52:30,200
  104. 线程ID:[QuartzNetDemo.WinService_Worker-3]
  105. 日志级别: INFO
  106. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  107. 描述:当前时间:2018-09-21 15:52:30,已经运行完毕!
  108.  
  109. 记录时间:2018-09-21 15:52:30,202
  110. 线程ID:[QuartzNetDemo.WinService_Worker-3]
  111. 日志级别: INFO
  112. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  113. 描述:=================================任务结束:QuartzNetDemo.WinService.Jobs.WriteTextToFileJob=================================
  114.  
  115. 记录时间:2018-09-21 15:52:31,191
  116. 线程ID:[QuartzNetDemo.WinService_Worker-5]
  117. 日志级别: INFO
  118. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  119. 描述:=================================任务开始:QuartzNetDemo.WinService.Jobs.WriteTextToFileJob=================================
  120.  
  121. 记录时间:2018-09-21 15:52:31,193
  122. 线程ID:[QuartzNetDemo.WinService_Worker-5]
  123. 日志级别: INFO
  124. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  125. 描述:当前时间:2018-09-21 15:52:31,正在运行...
  126.  
  127. 记录时间:2018-09-21 15:52:31,194
  128. 线程ID:[QuartzNetDemo.WinService_Worker-5]
  129. 日志级别: INFO
  130. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  131. 描述:当前时间:2018-09-21 15:52:31,接受到参数 "UserName" 的值等于 周星驰
  132.  
  133. 记录时间:2018-09-21 15:52:31,197
  134. 线程ID:[QuartzNetDemo.WinService_Worker-5]
  135. 日志级别: INFO
  136. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  137. 描述:当前时间:2018-09-21 15:52:31,接受到参数 "Msg" 的值等于 Hello world,欢迎使用 Quartz.net 调度组件
  138.  
  139. 记录时间:2018-09-21 15:52:31,198
  140. 线程ID:[QuartzNetDemo.WinService_Worker-5]
  141. 日志级别: INFO
  142. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  143. 描述:当前时间:2018-09-21 15:52:31,准备暂停 5 秒钟...
  144.  
  145. 记录时间:2018-09-21 15:52:33,199
  146. 线程ID:[QuartzNetDemo.WinService_Worker-4]
  147. 日志级别: INFO
  148. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  149. 描述:当前时间:2018-09-21 15:52:33,已经运行完毕!
  150.  
  151. 记录时间:2018-09-21 15:52:33,201
  152. 线程ID:[QuartzNetDemo.WinService_Worker-4]
  153. 日志级别: INFO
  154. 出错类: D:\WorkSpace\QuartzNetDemo.WinService\QuartzNetDemo.WinService.Jobs\FileUtil.cs 在第 22
  155. 描述:=================================任务结束:QuartzNetDemo.WinService.Jobs.WriteTextToFileJob=================================

运行效果图:

这个一个利用 Windows Service 挂载 Quartz (定时调度,也叫定时任务)的例子。

1. Windows Service 的名称和描述可以在 App.config 中的 appSettings 中配置。

2. 该 Windows Service 中的 Quartz 已经配置了持久化任务(即把任务信息保存到数据库),所以需要提前建立好数据库(建库脚本参考 Quartz.net 官方说明),并且配置连接字符串。

3. App.config 文件更改后,无须重新安装 Windows Services,只需要重启就可以了。

4. 通过在 quartz_jobs.xml 文件中注册任务,即可以不通过修改代码来完成“动态”注册任务,比如增加一个类库,编译后把 DLL 复制到 Windows Service 所在的目录下,可以不重启 Windows 服务。

5. 可以观察,当改变了 quartz_jobs.xml 文件中的配置后,打印出的日志信息的变化。

6. 我们在 quartz_jobs.xml 配置的 repeat-interval=3000,即 3 秒执行一次,但在 WriteTextToFileJob 中我们通过 Thread.Sleep(TimeSpan.FromSeconds(5)); 延迟了 5 秒,那么就会存在多个实例交错执行的情况,请观察日志。

7. 在 Quartz 的官方示例 example12 中有一个 RemoteServerExample、RemoteClientExample 例子,即可以远程注册任务,但要注意,需要把 Client 项目的 Job 所引用的所有程序集复制到 Server 所在的 Bin 目录,要不然会运行时会抛出无法找到 DLL 异常。且服务端和客户端所引用的 Quartz 的版本必须一致。Quartz 内部是通过 .NET Remoting 来实现的,把 Client 中的 Job 的元数据序列化给 Server 端,然后 Server 端再去反射、调用。

谢谢浏览!

Topshelf + QuartzNet 实现挂载在 WIndows Services 中的定时任务的更多相关文章

  1. Windows 系统文件夹目录挂载到 Linux服务器中

    在Windows系统文件上传到Linux服务器时有时候很麻烦,因为Linux无界面的系统不像Windows系统一样,可以直接复制粘贴,下面方法可以解决Windows系统文件拷贝到Linux服务器. 1 ...

  2. 用C#创建Windows服务(Windows Services)

    用C#创建Windows服务(Windows Services) 学习:  第一步:创建服务框架 创建一个新的 Windows 服务项目,可以从Visual C# 工程中选取 Windows 服务(W ...

  3. 当程序以Windows Services形式启动时当前路径不对

    当程序以Windows Services形式启动时当前路径不对 @(操作系统)[博客|dotNet] 很多时候我们需要将我们的程序写成利用Windows服务的形式来让它能够自启动.今天遇到一个问题,当 ...

  4. 解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

        在某国外大型汽车公司BI项目中,有一个子项目,需要通过大屏幕展示销售报表,程序需要自动启动和关闭.开发人员在开发过程中,发现在Win7的service中不能直接操作UI进程,调查过程中,发现如 ...

  5. [转]解决vista和win7在windows服务中交互桌面权限问题:穿透Session 0 隔离

    服务(Service)对于大家来说一定不会陌生,它是Windows 操作系统重要的组成部分.我们可以把服务想像成一种特殊的应用程序,它随系统的“开启-关闭”而“开始-停止”其工作内容,在这期间无需任何 ...

  6. Windows Services Windows Services的操作

    Windows Services的操作 一.服务的创建: 1.新建项目——Windows服务 2.这是每个人都会犯的错误,新建一个项目后,都会按F5(运行),就会出现如下错误: 3.安装服务有很多种方 ...

  7. linux挂载本地windows分区或目录

    linux挂载本地windows分区或目录 一.linux挂载本地windows硬盘分区 向虚拟机Centos添加本地windows硬盘 注:(添加物理硬盘后,在centos操作会直接写入本地硬盘) ...

  8. 使用Topshelf组件构建简单的Windows服务

    很多时候都在讨论是否需要了解一个组件或者一个语言的底层原理这个问题,其实我个人觉得,对于这个问题,每个人都有自己的看法,个人情况不同,选择的方式也就会不同了.我个人觉得无论学习什么,都应该尝试着去了解 ...

  9. windows 服务中托管asp.net core

    在windows 服务中托管asp.net core SDK 2.1.300 官方示例 1.添加运行标识符 xml <PropertyGroup> <TargetFramework& ...

随机推荐

  1. 利用zabbix监控ogg进程(Windows平台下)

    本文给大家介绍如何监控windows平台下的ogg程序.(注:所有操作都在administrator用户下面进行操作) 监控linux平台下的ogg程序请看:https://www.cnblogs.c ...

  2. OA传SAP设置(备忘)

    package com.seeyon.apps.ext.kk.flow.hc; import java.rmi.RemoteException; import java.text.SimpleDate ...

  3. springmvc学习笔记三:整合JDBC,简单案例==数据库事务配置(切面)

    package cn.itcast.bean; import org.springframework.jdbc.core.PreparedStatementSetter; public class U ...

  4. 获取本设备IP地址

    获取本设备(Android.PC)IP地址 public string GetLocalIP() { try { string HostName = Dns.GetHostName(); //得到主机 ...

  5. hadoop mapreduce求解有序TopN

    利用hadoop的map和reduce排序特性实现对数据排序取TopN条数据. 代码参考:https://github.com/asker124143222/wordcount 1.样本数据,假设是订 ...

  6. [转]Eclipse插件开发之基础篇(3) 插件的测试与调试

    原文地址:http://www.cnblogs.com/liuzhuo/archive/2010/08/17/eclipse_plugin_1_1_2.html 1. 使用JUnit对插件进行测试 E ...

  7. CodeForces - 1007A (思维+双指针)

    题意 https://vjudge.net/problem/CodeForces-1007A 对一个序列重排,使得新的数比原来的数大对应的位置个数最多. 思路 举个栗子,比如1 2 2 3 3 3 3 ...

  8. OpenTelemetry项目中的Observability

    最近,在实操zipkin,jaeger,opencensus,opentracing,opentelemetry等. opentelemetry将Observability提到了重要页面, 并进行了讲 ...

  9. luoguP5094 [USACO04OPEN]MooFest 狂欢节

    get 到的 这种需要求 含 max 的式子,枚举最大值的方法非常普遍. 类似的,还有含 min , gcd 的式子,枚举他们也很普遍 主要难点 我们首先想到,先按 v 从小到大排序,因为这样既可以简 ...

  10. jmeter beanshell断言接口自动化实例

    一.JMeter介绍 Apache JMeter是一款优秀的开源性能测试工具,在国外无论是在性能测试还是接口测试领域都有着非常高的使用率,但由于本身没有完善的中文文档以及典型开源工具特点(界面不美观) ...