1、 New console application
2、 Select the item, right-click manage nuget package, and add four:
Quartz
Quartz.Plugins
Topshelf
log4net
3、 Create project file
Three configuration files: must be placed in the project root directory.
(1)log4net.config


View Code
(2)quartz.config


true
SampleJob
SampleGroup
Sample job for Quartz Server
QuartzTopshelf.Jobs.SampleJob, QuartzTopshelf
true
false
key1
value1
key2
value2
SampleSimpleTrigger
SampleSimpleGroup
Simple trigger to simply fire sample job
SampleJob
SampleGroup
SmartPolicy
-1
10000
SampleCronTrigger
SampleCronGroup
Cron trigger to simply fire sample job
SampleJob
SampleGroup
SmartPolicy
0/10 * * * * ?
SampleCalendarIntervalTrigger
SampleCalendarIntervalGroup
Calendar interval trigger to simply fire sample job
SampleJob
SampleGroup
SmartPolicy
15
Second
View Code
It can also be in the project configuration file app Config, you don’t need to configure quartz config
App.config


View Code
(3)quartz_ jobs. XML # I won’t explain specifically. If you don’t understand, you can check quartz NET


true
SampleJob
SampleGroup
Sample job for Quartz Server
Quartz.Server.Jobs.SampleJob, Quartz.Server
true
false
key1
value1
key2
value2
SampleSimpleTrigger
SampleSimpleGroup
Simple trigger to simply fire sample job
SampleJob
SampleGroup
SmartPolicy
-1
10000
SampleCronTrigger
SampleCronGroup
Cron trigger to simply fire sample job
SampleJob
SampleGroup
SmartPolicy
0/10 * * * * ?
SampleCalendarIntervalTrigger
SampleCalendarIntervalGroup
Calendar interval trigger to simply fire sample job
SampleJob
SampleGroup
SmartPolicy
15
Second
View Code
Three types of files:
(1)Configuration. CS configuration class


using System.Collections.Specialized;
using System.Configuration;
namespace QuartzTopshelf
{
///
///Configuration of timing service
///
public class Configuration
{
private const string PrefixServerConfiguration = "quartz.server";
private const string KeyServiceName = PrefixServerConfiguration + ".serviceName";
private const string KeyServiceDisplayName = PrefixServerConfiguration + ".serviceDisplayName";
private const string KeyServiceDescription = PrefixServerConfiguration + ".serviceDescription";
private const string KeyServerImplementationType = PrefixServerConfiguration + ".type";
private const string DefaultServiceName = "QuartzServer";
private const string DefaultServiceDisplayName = "Quartz Server";
private const string DefaultServiceDescription = "Quartz Job Scheduling Server";
private static readonly string DefaultServerImplementationType = typeof(QuartzServer).AssemblyQualifiedName;
private static readonly NameValueCollection configuration;
///
///Initialize configuration class
///
static Configuration()
{
configuration = (NameValueCollection)ConfigurationManager.GetSection("quartz");
}
///
///Gets the name of the service
///
///Name of the service
public static string ServiceName
{
get { return GetConfigurationOrDefault(KeyServiceName, DefaultServiceName); }
}
///
///Gets the display name of the service
///
///Display name of the service
public static string ServiceDisplayName
{
get { return GetConfigurationOrDefault(KeyServiceDisplayName, DefaultServiceDisplayName); }
}
///
///Get service description
///
///Service description
public static string ServiceDescription
{
get { return GetConfigurationOrDefault(KeyServiceDescription, DefaultServiceDescription); }
}
///
///Gets the type name of the server implementation
///
///Type of server implementation
public static string ServerImplementationType
{
get { return GetConfigurationOrDefault(KeyServerImplementationType, DefaultServerImplementationType); }
}
///
///Returns the configuration value with the given key. If the configuration does not exist, the default value is returned.
///
///Key for reading configuration
///The default value returned when the configuration is not found
///Configuration value
private static string GetConfigurationOrDefault(string configurationKey, string defaultValue)
{
string retValue = null;
if (configuration != null)
{
retValue = configuration[configurationKey];
}
if (retValue == null || retValue.Trim().Length == 0)
{
retValue = defaultValue;
}
return retValue;
}
}
}
View Code
(2)QuartzServer. CS timing service class


using System;
using System.Threading.Tasks;
using log4net;
using Quartz;
using Quartz.Impl;
using Topshelf;
namespace QuartzTopshelf
{
///
/// Service interface for core Quartz.NET server.
///
public interface IQuartzServer
{
///
/// Initializes the instance of .
/// Initialization will only be called once in server's lifetime.
///
Task Initialize();
///
/// Starts this instance.
///
void Start();
///
/// Stops this instance.
///
void Stop();
///
/// Pauses all activity in scheduler.
///
void Pause();
///
/// Resumes all activity in server.
///
void Resume();
}
///
/// The main server logic.
///
public class QuartzServer : ServiceControl, IQuartzServer
{
private readonly ILog logger;
private ISchedulerFactory schedulerFactory;
private IScheduler scheduler;
///
/// Initializes a new instance of the class.
///
public QuartzServer()
{
logger = LogManager.GetLogger(GetType());
}
///
/// Initializes the instance of the class.
///
public virtual async Task Initialize()
{
try
{
schedulerFactory = CreateSchedulerFactory();
scheduler = await GetScheduler().ConfigureAwait(false);
}
catch (Exception e)
{
logger.Error("Server initialization failed:" + e.Message, e);
}
}
///
/// Gets the scheduler with which this server should operate with.
///
///
protected virtual Task GetScheduler()
{
return schedulerFactory.GetScheduler();
}
///
/// Returns the current scheduler instance (usually created in
/// using the method).
///
protected virtual IScheduler Scheduler => scheduler;
///
/// Creates the scheduler factory that will be the factory
/// for all schedulers on this instance.
///
///
protected virtual ISchedulerFactory CreateSchedulerFactory()
{
return new StdSchedulerFactory();
}
///
/// Starts this instance, delegates to scheduler.
///
public virtual void Start()
{
try
{
scheduler.Start();
}
catch (Exception ex)
{
logger.Fatal(string.Format("Scheduler start failed: {0}", ex.Message), ex);
throw;
}
//logger.Info("Scheduler started successfully");
}
///
/// Stops this instance, delegates to scheduler.
///
public virtual void Stop()
{
try
{
scheduler.Shutdown(true);
}
catch (Exception ex)
{
logger.Error(string.Format("Scheduler stop failed: {0}", ex.Message), ex);
throw;
}
//logger.Info("Scheduler shutdown complete");
}
///
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
///
public virtual void Dispose()
{
// no-op for now
}
///
/// Pauses all activity in scheduler.
///
public virtual void Pause()
{
scheduler.PauseAll();
}
///
/// Resumes all activity in server.
///
public void Resume()
{
scheduler.ResumeAll();
}
///
/// TopShelf's method delegated to .
///
public bool Start(HostControl hostControl)
{
Start();
return true;
}
///
/// TopShelf's method delegated to .
///
public bool Stop(HostControl hostControl)
{
Stop();
return true;
}
///
/// TopShelf's method delegated to .
///
public bool Pause(HostControl hostControl)
{
Pause();
return true;
}
///
/// TopShelf's method delegated to .
///
public bool Continue(HostControl hostControl)
{
Resume();
return true;
}
}
}
View Code
(3)QuartzServerFactory. CS # factory class


using System;
using System.Reflection;
using log4net;
namespace QuartzTopshelf
{
///
///Factory class used to create quartz service implementation
///
public class QuartzServerFactory
{
private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
///
///Create quartz Net service core
///
///
public static QuartzServer CreateServer()
{
string typeName = Configuration.ServerImplementationType;
Type t = Type.GetType(typeName, true);
//logger. Debug ("creating a new instance of server type '" + typename + "'");
QuartzServer retValue = (QuartzServer)Activator.CreateInstance(t);
//logger. Debug ("instance successfully created");
return retValue;
}
}
}
View Code
Service startup class: program cs


using System.IO;
using System.Reflection;
using Topshelf;
namespace QuartzTopshelf
{
public static class Program
{
static void Main(string[] args)
{
//Change from the directory of the service account to a more logical directory
Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);
var logRepository = log4net.LogManager.GetRepository(Assembly.GetEntryAssembly());
log4net.Config.XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config"));
HostFactory.Run(x => {
x.RunAsLocalSystem();
x.SetDescription(Configuration.ServiceDescription);
x.SetDisplayName(Configuration.ServiceDisplayName);
x.SetServiceName(Configuration.ServiceName);
x.Service(factory =>
{
QuartzServer server = QuartzServerFactory.CreateServer();
server.Initialize().GetAwaiter().GetResult();
return server;
});
});
}
}
}
View Code
4、 Add job class, and in quartz_ jobs. XML configuration job trigger rule
SampleJob.cs


using System;
using System.Collections;
using System.Reflection;
using System.Threading.Tasks;
using log4net;
using Quartz;
namespace QuartzTopshelf.Jobs
{
///
/// A sample job that just prints info on console for demostration purposes.
///
public sealed class SampleJob : IJob
{
private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
///
/// Called by the when a
/// fires that is associated with the .
///
///
/// The implementation may wish to set a result object on the
/// JobExecutionContext before this method exits. The result itself
/// is meaningless to Quartz, but may be informative to
/// s or
/// s that are watching the job's
/// execution.
///
/// The execution context.
public async Task Execute(IJobExecutionContext context)
{
//Pass parameters through configuration file
JobDataMap dataMap = context.JobDetail.JobDataMap;
string key1 = dataMap.GetString("key1");
logger.Info("key1 : " + key1);
string key2 = dataMap.GetString("key2");
logger.Info("key2 : " + key2);
logger.Info("SampleJob running...");
//Thread.Sleep(TimeSpan.FromSeconds(5));
await Console.Out.WriteLineAsync("SampleJob is executing.");
logger.Info("SampleJob run finished.");
}
}
}
View Code
The job trigger rule is above quartz_ jobs. Configuration in XML file
In particular, there are several common methods of job trigger:
-
Simpletrigger: simple trigger (key)
-
Calendarintervaltrigger: calendar trigger (can be researched by yourself)
-
Crontrigger: cron expression trigger (key)
Project structure diagram:
In addition, you can set parameters to pass to the job through the configuration file:
Relevant source code address:https://gitee.com/wyft/QuartzTopshelf