在.net平台使用Quartz+Topshelf创建windows服务

背景

对于使用Windows操作系统的人来说,Windows Service(Windows服务)应该不会陌生。在工作中我们经常需要定时处理一些业务,例如晚上零晨抓取一批数据,如果我们用C#语言创建windows服务也是可以的,但是步骤比较繁琐,不好调试。所以上篇文章中我使用windows计划执行控制台程序,但是呢也不是足够完美,因为计划一旦开始执行时控制台的窗口会被唤起,这时如果有人关掉了该窗口,那么也会影响业务的处理(毕竟公司的服务器多个程序员使用嘛)。

鉴于以上种种原因,我查找了一些资料,看到老外使用Topshelf来创建windows服务,比较完美。下面开始演示步骤;

第一步:

打开VS创建一个控制台程序,这里我去明叫“MyQuartzWindowsService”(版本选择4.6.1或以上),当然4.6.1以下版本也可以,只是选择Topshelf时不要选择最高版本。

第二步:

打开nuget搜索“Topshelf”进行安装
在.net平台使用Quartz+Topshelf创建windows服务

第三步:

打开nuget搜索“Quartz”进行安装
在.net平台使用Quartz+Topshelf创建windows服务

第四步:

创建一个定时服务类“QuartzServiceRunner”,并写入以下代码

 {
  private readonly IScheduler scheduler;    
  public QuartzServiceRunner()
   {
     scheduler = StdSchedulerFactory.GetDefaultScheduler();
   }
    public void Start()
    {
    //从配置文件中读取任务启动时间
     string cronExpr = ConfigurationManager.AppSettings["cronExpr"];
     IJobDetail job = JobBuilder.Create<DeleteDomainJob>().WithIdentity("job1", "group1").Build();
      //创建任务运行的触发器
      ITrigger trigger = TriggerBuilder.Create()
         .WithIdentity("triggger1", "group1")
         .WithSchedule(CronScheduleBuilder.CronSchedule(new CronExpression(cronExpr)))
         .Build();
       //启动任务
        scheduler.ScheduleJob(job, trigger);
        scheduler.Start();
        scheduler.Start();         
     }
     public void Stop()
      {
       scheduler.Clear();
      }
     public bool Continue()
      {
        scheduler.ResumeAll();
        return true;
      }
      public bool Pause()
       {
        scheduler.PauseAll();
        return true;
      }
    }
第五步:

创建一个业务类"DeleteDomainJob"并继承IJob

 {    
   public void Execute(IJobExecutionContext context)
    {           
      LogHelper.Writelog($"任务开始{DateTime.Now}");  
        //这里是业务处理,我就简单记录下日志  
     }     
  }

关于LogHelper类这里也放出来

 {
  public static void Writelog(string str)
   {
   Task.Run(() =>
    {
     string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log.txt");
      string logContent = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}:{str}\r\n";
      File.AppendAllText(filePath, logContent);
    });
     }
 }
第六步:

控制台Program类中写入一下代码(关于Topshelf)

{
  static void Main(string[] args)
  {         
    HostFactory.Run(x =>
     {
       x.Service<QuartzServiceRunner>(s =>
      {
        s.ConstructUsing(name => new QuartzServiceRunner());
         s.WhenStarted(tc => tc.Start());
          s.WhenStopped(tc => tc.Stop());
      });
       x.RunAsLocalSystem();
       x.StartAutomatically();
       x.SetDescription("火虫网定时服务");
       x.SetDisplayName("火虫网定时服务");
       x.SetServiceName("火虫网定时服务");
       });
      }
 }
第七步:安装服务

我们定位到程序debug路径中(你也可以选择release下编译),启用命令提示符(以管理员身份运行),并用MyQuartzWindowsService.exe install命令安装服务

在.net平台使用Quartz+Topshelf创建windows服务
卸载命令也很简单,MyQuartzWindowsService.exe unistall。

最后我们来看一下服务到底安装好没,在Windows操作系统中,我们可以在”运行”窗口中运行service.msc:
在.net平台使用Quartz+Topshelf创建windows服务
我们看下日志到底写没写进去,看下图
在.net平台使用Quartz+Topshelf创建windows服务

总结

使用C#语言创建windows服务也是可以的,但是碍于难调试,步骤比较繁琐,这里我使用Topshelf来创建服务,但是我们经常都写成定时服务,有具体的时间点,所以这里我使用Quartz+Topshelf创建windows服务来供大家参考,把更多的重心放在业务处理中。

上一篇:极简实用的Asp.NetCore框架再新增商城模块


下一篇:关于数据库建表是否建立外键的争论,你有什么样的观点?