Combination of quartz and topshelf to realize window timing service

Time:2022-5-5

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

Combination of quartz and topshelf to realize window timing serviceCombination of quartz and topshelf to realize window timing service

View Code

(2)quartz.config 

Combination of quartz and topshelf to realize window timing serviceCombination of quartz and topshelf to realize window timing service

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

Combination of quartz and topshelf to realize window timing serviceCombination of quartz and topshelf to realize window timing service

View Code

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

Combination of quartz and topshelf to realize window timing serviceCombination of quartz and topshelf to realize window timing service

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

Combination of quartz and topshelf to realize window timing serviceCombination of quartz and topshelf to realize window timing service

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

Combination of quartz and topshelf to realize window timing serviceCombination of quartz and topshelf to realize window timing service

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

Combination of quartz and topshelf to realize window timing serviceCombination of quartz and topshelf to realize window timing service

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

Combination of quartz and topshelf to realize window timing serviceCombination of quartz and topshelf to realize window timing service

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

Combination of quartz and topshelf to realize window timing serviceCombination of quartz and topshelf to realize window timing service

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 

 

Recommended Today

Modify user information changeinfo

When judging the persistence layer: Problem: there is such a problem when modifying user information. For example: the user’s email is not required. It was not empty originally. At this time, the user deletes the mailbox information and submits it. At this time, if it is not empty to judge whether it needs to be […]