• Host服务


    这也是看网上的例子自己跟着配置做的一个小demo,这里记录一下。

    一、创建一个空的控制台应用程序

    二、安装所需dll 

      1.Quartz 
        Install-Package Quartz -Version 2.3.3
      2.Owin
        Install-Package Owin -Version 1.0.0(这个暂时装上)
      3.TopShelf
        Install-Package TopShelf -Version 3.3.1
      4.log4net
        Install-Package log4net -Version 2.0.8
      5.TopShelf.log4net
        Install-Package Topshelf.Log4Net -Version 3.3.1

     这里我把版本都标记出来是因为NuGet安装的时候有可能最新的版本会不兼容的问题,如果出现请降版本安装。

    三、手动创建

      1.log4net.config

      

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
      </configSections>
    
      <log4net>
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <!--日志路径-->
          <param name= "File" value= "Log"/>
          <!--是否是向文件中追加日志-->
          <param name= "AppendToFile" value= "true"/>
          <!--log保留天数-->
          <param name= "MaxSizeRollBackups" value= "10"/>
          <!--日志文件名是否是固定不变的-->
          <param name= "StaticLogFileName" value= "false"/>
          <!--日志文件名格式为:2008-08-31.log-->
          <param name= "DatePattern" value= "yyyy-MM-dd&quot;.read.log&quot;"/>
          <!--日志根据日期滚动-->
          <param name= "RollingStyle" value= "Date"/>
          <layout type="log4net.Layout.PatternLayout">
            <param name="ConversionPattern" value="%date{HH:mm:ss,fff} %-5p-%m%n" />
          </layout>
        </appender>
    
        <!-- 控制台前台显示日志 -->
        <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
          <mapping>
            <level value="ERROR" />
            <foreColor value="Red, HighIntensity" />
          </mapping>
          <mapping>
            <level value="Info" />
            <foreColor value="Green" />
          </mapping>
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
          </layout>
    
          <filter type="log4net.Filter.LevelRangeFilter">
            <param name="LevelMin" value="Info" />
            <param name="LevelMax" value="Fatal" />
          </filter>
        </appender>
    
        <root>
          <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
          <level value="all" />
          <appender-ref ref="ColoredConsoleAppender"/>
          <appender-ref ref="RollingLogFileAppender"/>
        </root>
    
      </log4net>
    </configuration>
    View Code

      2.quartz.config

    # You can configure your scheduler in either <quartz> configuration section
    # or in quartz properties file
    # Configuration section has precedence
    
    quartz.scheduler.instanceName = QuartzTest
    
    # configure thread pool info
    quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
    quartz.threadPool.threadCount = 10
    quartz.threadPool.threadPriority = Normal
    
    # job initialization plugin handles our xml reading, without it defaults are used
    quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz
    quartz.plugin.xml.fileNames = ~/quartz_jobs.xml
    
    # export this server to remoting context
    #quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
    #quartz.scheduler.exporter.port = 560
    #quartz.scheduler.exporter.bindName = QuartzScheduler
    #quartz.scheduler.exporter.channelType = tcp
    #quartz.scheduler.exporter.channelName = httpQuartz
    View Code

      3.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>
    
        <!--TestJob测试 任务配置 -->
        <job>
          <name>TestJob</name>
          <group>Test</group>
          <description>TestJob测试</description>
          <job-type>HostProject.QuartzJobs.TestJob,HostProject</job-type>
          <durable>true</durable>
          <recover>false</recover>
        </job>
        <trigger>
          <cron>
            <name>TestJobTrigger</name>
            <group>Test</group>
            <job-name>TestJob</job-name>
            <job-group>Test</job-group>
            <!-- 从start-time起,每5s执行一次IJob.Execute -->
            <start-time>2012-01-22T00:00:00+08:00</start-time>
            <cron-expression>0/5 * * * * ?</cron-expression>
          </cron>
        </trigger>
    
      </schedule>
    </job-scheduling-data>
    View Code

    四、创建 ServiceRunner.cs

     public class ServiceRunner : ServiceControl, ServiceSuspend
        {
            private readonly IScheduler _IScheduler;
            public ServiceRunner()
            {
                _IScheduler = StdSchedulerFactory.GetDefaultScheduler();
            }
            public bool Start(HostControl hostControl)
            {
                _IScheduler.Start();
                return true;
            }
    
            public bool Stop(HostControl hostControl)
            {
                _IScheduler.Shutdown();
                return true;
            }
    
            public bool Continue(HostControl hostControl)
            {
                _IScheduler.ResumeAll();
                return true;
            }
    
            public bool Pause(HostControl hostControl)
            {
                _IScheduler.PauseAll();
                return true;
            }
        }
    View Code

    五、TestJob

      public sealed class TestJob:IJob
        {
            public void Execute(IJobExecutionContext context)
            {
                CommonHelper.AppLogger.InfoFormat("TestJob测试");
                try
                {
    
                    //模拟调用存储过程,更新商品库存
    
                    string connStr = "Data Source=.;Initial Catalog=test;User Id=sa;Password=p@ss!123;";
    
                    using (SqlConnection conn = new SqlConnection(connStr))
                    {
    
                        using (SqlCommand cmd = new SqlCommand())
                        {
    
                            conn.Open();
    
                            cmd.Connection = conn;
    
                            cmd.CommandType = CommandType.StoredProcedure;
    
                            cmd.CommandText = "proc_UpdateInventory";
    
                            Random random = new Random();
    
                            SqlParameter[] paras = new SqlParameter[]
    
                        {
    
                            new SqlParameter()
    
                            {
    
                                ParameterName = "@GoodsId",
    
                                SqlDbType = SqlDbType.Int,
    
                                Value =  random.Next(1, 4)
    
                            },
    
                            new SqlParameter()
    
                            {
    
                                ParameterName = "@Inventory",
    
                                SqlDbType = SqlDbType.Int,
    
                                Value = random.Next(1, 100)
    
                            }
    
                        };
    
                            cmd.Parameters.AddRange(paras);
    
                            int rowCount = cmd.ExecuteNonQuery();   //exec proc_UpdateInventory @GoodsId=1,@Inventory=25
    
                            if (rowCount > 0)
    
    
                                CommonHelper.AppLogger.InfoFormat("商品:{0},库存已更新,新的库存为:{1}", paras[0].Value, paras[1].Value);
    
                            else
    
                                CommonHelper.AppLogger.InfoFormat("更新商品库失败,无受影响记录:{0}", rowCount);
    
                        }
    
                    }
    
                }
    
                catch (Exception ex)
                {
    
                    CommonHelper.AppLogger.ErrorFormat("UpdateInventoryJob 作业执行异常:{0}", ex);
    
                }
            }
        }
    View Code

    六、CommonHelper

      class CommonHelper
        {
            public static readonly ILog AppLogger = log4net.LogManager.GetLogger("ColoredConsoleAppender");
            static CommonHelper() { }
        }
    View Code

    七、Program中代码调用

     static void Main(string[] args)
            {
               XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
    
                HostFactory.Run(x => {
                    x.UseLog4Net();
                    x.Service<ServiceRunner>();
                    x.RunAsLocalSystem();
    
                    x.SetDescription("Quartz+TopShelf实现Windows服务作业调度的一个示例Demo");
                    x.SetDisplayName("QuartzTopShelfDemo服务");
                    x.SetServiceName("QuartzTopShelfDemoService");
    
                    x.EnablePauseAndContinue();
    
                });
            }
    View Code

    八、特别注意

     这三个文件手动创建,默认是“不复制”,这里需要修改为“始终复制”

    这样一个Host便可以运行起来了。

    九、安装到Windows

    用cmd命令行打开这个文件夹

    执行命令  : HostProject.exe install

    卸载:HostProject.exe uninstall

    十、SQL脚本(先把存储过程执行过在运行项目)

    IF ( OBJECT_ID('Goods', 'U') IS NOT NULL )
        DROP TABLE Goods;
    
    GO
    
    CREATE TABLE Goods
        (
          Id INT IDENTITY(1, 1)
                 NOT NULL ,
          Name NVARCHAR(30) NOT NULL ,
          Inventory INT
            NOT NULL
            CONSTRAINT PK_Goods_Id PRIMARY KEY CLUSTERED ( Id ASC ) ON [PRIMARY]
        )
    ON  [PRIMARY];
    
    INSERT  INTO Goods
    VALUES  ( '大米', 0 ),
            ( '香蕉', 0 ),
            ( '苹果', 0 );
    
    SELECT  *
    FROM    Goods;
    
    IF ( OBJECT_ID('proc_UpdateInventory', 'P') IS NOT NULL )
        DROP PROCEDURE proc_UpdateInventory;
    
    GO
    
    CREATE PROCEDURE proc_UpdateInventory
        (
          @GoodsId INT ,
          @Inventory INT
        )
    AS
        UPDATE  Goods
        SET     Inventory = @Inventory
        WHERE   Id = @GoodsId;
    
    GO
    View Code

    十一、说明

      这里没有对使用进行说明,还有Owin的还没用,后面有时间会补上。

    十二、效果

  • 相关阅读:
    Gitlab -- 基本操作
    javascript--事件委托
    javascript--Dom 二级事件
    Tableau学习笔记之五
    Tableau学习笔记之二
    Tableau学习笔记之四
    Tableau学习笔记之三
    Tableau学习笔记之一
    Qt使用Cookies对网站操作之Get和POST
    C++ 使用Htmlcxx解析Html内容(VS编译库文件)
  • 原文地址:https://www.cnblogs.com/myloveblogs/p/9960129.html
Copyright © 2020-2023  润新知