Host服务
阅读原文时间:2023年07月09日阅读:3

这也是看网上的例子自己跟着配置做的一个小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

  2.quartz.config \# You can configure your scheduler in either 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 = 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 = #quartz.scheduler.exporter.bindName = QuartzScheduler #quartz.scheduler.exporter.channelType = tcp #quartz.scheduler.exporter.channelName = httpQuartz   3.quartz\_jobs.xml

true

<!--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>--22T00::+:</start-time>  
    <cron-expression>/ \* \* \* \* ?</cron-expression>  
  </cron>  
</trigger>


四、创建 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;  
    }  
}

五、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(, )

                    },

                    new SqlParameter()

                    {

                        ParameterName = "@Inventory",

                        SqlDbType = SqlDbType.Int,

                        Value = random.Next(, )

                    }

                };

                    cmd.Parameters.AddRange(paras);

                    int rowCount = cmd.ExecuteNonQuery();   //exec proc\_UpdateInventory @GoodsId=1,@Inventory=25

                    if (rowCount > )

                        CommonHelper.AppLogger.InfoFormat("商品:{0},库存已更新,新的库存为:{1}", paras\[\].Value, paras\[\].Value);

                    else

                        CommonHelper.AppLogger.InfoFormat("更新商品库失败,无受影响记录:{0}", rowCount);

                }

            }

        }

        catch (Exception ex)  
        {

            CommonHelper.AppLogger.ErrorFormat("UpdateInventoryJob 作业执行异常:{0}", ex);

        }  
    }  
}

六、CommonHelper

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

七、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();

        });  
    }

八、特别注意

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

这样一个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

十一、说明

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

十二、效果

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器