C# windows服务开发

创建一个控制台应用程序

控制台应用程序需要加Common.Logging.dll,Common.Logging.Core.dll,Topshelf.dll,Topshelf.Log4Net.dll
如果服务有操作数据库,则还需加EntityFramework.dll和EntityFramework.SqlServer.dll
Main方法体插入代码

		static void Main(string[] args)
        {
            HostFactory.Run(x =>
            {
                //x.UseAssemblyInfoForServiceInfo();
                x.Service<BackTaskService>(s =>
                {
                    s.ConstructUsing(name => new 后台任务调度BLL());
                    s.WhenStarted(tc => tc.OnStart(Environment.CurrentDirectory));
                    s.WhenStopped(tc => tc.OnStop());
                });
                x.SetServiceName("服务名称");
                x.SetDisplayName("服务描述");
                x.SetInstanceName("项目实例名称");
                x.SetDescription("详细描述");
                x.RunAsLocalSystem();
                x.StartAutomatically();
            });
        }

创建后台任务调用类

需要注意私有构造函数里面需要读取xml配置文件:quartz_jobs.xml

	public class 后台任务调度BLL
    {
        protected static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        /// <summary>
        /// SchedulerFactory接口私有变量
        /// </summary>
        /// <remarks>
        /// <para>  Wu Changhong(2019/10/25)</para>
        /// </remarks>
        private ISchedulerFactory schedulerFactory;

        /// <summary>
        /// Scheduler接口私有变量
        /// </summary>
        /// <remarks>
        /// <para>  Wu Changhong(2019/10/25)</para>
        /// </remarks>
        private IScheduler scheduler;

        /// <summary>
        /// 私有构造函数
        /// </summary>
        /// <remarks>
        /// <para>  Wu Changhong(2019/10/25)</para>
        /// </remarks>
        public 后台任务调度BLL()
        {
            NameValueCollection properties = new NameValueCollection();
            properties["quartz.scheduler.instanceName"] = "XmlConfiguredInstance";
            properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
            properties["quartz.threadPool.threadCount"] = "10";
            properties["quartz.threadPool.threadPriority"] = "Normal";

            // job initialization plugin handles our xml reading, without it defaults are used
            properties["quartz.plugin.xml.type"] = "Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz";
            properties["quartz.plugin.xml.fileNames"] = "~/quartz_jobs.xml";
            schedulerFactory = new StdSchedulerFactory(properties);
            //scheduler = schedulerFactory.GetScheduler();
        }

        public string RootPath { get; set; }

        /// <summary>
        /// 启动任务
        /// </summary>
        /// <remarks>
        /// <para>  Wu Changhong(2019/10/25)</para>
        /// </remarks>
        public void OnStart(string rootPath)
        {
            if (scheduler != null)
                return;

            try
            {
                RootPath = rootPath;
                log.Info("站点物理路径:" + RootPath);
                if (scheduler == null)
                {
                    scheduler = schedulerFactory.GetScheduler();
                }
                scheduler.Start();
                log.Info("后台任务启动");
            }
            catch (Exception e)
            {
                log.Error(e.Message, e);
            }
        }

        /// <summary>
        /// 停止任务
        /// </summary>
        /// <remarks>
        /// <para>  Wu Changhong(2019/10/25)</para>
        /// </remarks>
        public void OnStop()
        {
            try
            {
                if (scheduler != null)
                    scheduler.Shutdown(true);
                log.Info("后台任务停止");
            }
            catch (Exception e)
            {
                log.Error(e.Message, e);
            }
        }

        /// <summary>
        /// 暂停任务
        /// </summary>
        /// <remarks>
        /// <para>  Wu Changhong(2019/10/25)</para>
        /// </remarks>
        public void OnPause()
        {
            try
            {
                if (scheduler != null)
                    scheduler.PauseAll();
            }
            catch (Exception e)
            {
                log.Error(e.Message, e);
            }
        }

        /// <summary>
        /// 继续任务
        /// </summary>
        /// <remarks>
        /// <para>  Wu Changhong(2019/10/25)</para>
        /// </remarks>
        public void OnContinue()
        {
            try
            {
                if (scheduler != null)
                    scheduler.ResumeAll();
            }
            catch (Exception e)
            {
                log.Error(e.Message, e);
            }
        }
    }

quartz_jobs.xml配置文件内容

<?xml version="1.0" encoding="UTF-8"?>

<!-- This file contains job definitions in schema version 2.0 format -->

<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">

  <processing-directives>
    <overwrite-existing-data>true</overwrite-existing-data>
  </processing-directives>

  <schedule>

    <!--任务配置类Job-->
    <job>
      <name>任务配置类名称</name>
      <group>任务配置类分组名称</group>
      <description>说明</description>
      <job-type>任务配置类完整引用地址.OrderPayQueryJob,任务配置类项目引用地址</job-type>
      <durable>true</durable>
      <recover>false</recover>
    </job>
    <trigger>
      <cron>
        <name>OrderPayQueryJobTrigger</name>
        <group>任务配置类分组名称</group>
        <job-name>任务配置类名称</job-name>
        <job-group>任务配置类分组名称</job-group>
        <start-time>2017-06-20T00:00:00+08:00</start-time>
        <cron-expression>0/1 * * * * ?</cron-expression><!--请求次数控制(参见cron表达式)-->
      </cron>
    </trigger>

    <!--任务配置类二Job-->
    <job>
      <name>任务配置类名称</name>
      <group>任务配置类分组名称</group>
      <description>说明</description>
      <job-type>任务配置类完整引用地址.OrderPayQueryJob,任务配置类项目引用地址</job-type>
      <durable>true</durable>
      <recover>false</recover>
    </job>
    <trigger>
      <cron>
        <name>OrderPayQueryJobTrigger</name>
        <group>任务配置类分组名称</group>
        <job-name>任务配置类名称</job-name>
        <job-group>任务配置类分组名称</job-group>
        <start-time>2017-06-20T00:00:00+08:00</start-time>
        <cron-expression>0/1 * * * * ?</cron-expression><!--请求次数控制(参见cron表达式)-->
      </cron>
    </trigger>
 

  </schedule>
</job-scheduling-data>

任务配置类

 public class OrderPayQueryJob : BaseJob
    {
        protected static log4net.ILog log =
            log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        /// <summary>
        /// 同步处理的变量
        /// </summary>
        private static readonly object sysObject = new object();

      
        /// <summary>
        /// 是否正在执行
        /// </summary>
        private static bool isDoing = false;

       

        /// <summary>
        /// 活动报名Job
        /// </summary>
        protected override void ExecuteJob()
        {
            try
            {
                lock (sysObject)
                {
                    if (isDoing)
                        return;
                    isDoing = true;
                }
                try
                {
                    Execute();
                }
                finally
                {
                    isDoing = false;
                }
            }
            catch (Exception em)
            {
                isDoing = false;
                log.Error(em);
            }
        }
        private void Execute()
        {
             //自己的业务
        }

         
    }

任务继承BaseJob 类

public abstract class BaseJob : IJob
    {
        protected static log4net.ILog log =
            log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        /// <summary>
        /// Job的实现
        /// </summary>
        /// <param name="context">Job执行的Context</param>
        /// <remarks>
        /// <para> 2019/10/25</para>
        /// </remarks>
        public void Execute(IJobExecutionContext context)
        {
            ExecuteJob();
        }

        /// <summary>
        /// 调用具体的Job实现
        /// </summary>
        protected abstract void ExecuteJob();
    }

安装和卸载服务

服务名称.exe install
服务名称.exe uninstall
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值