基于Coravel定时任务之计算总页数


1 应用背景

在物联网系统中,需要计算底端所有设备的总数,除以分页每页显示数量,进行一个总页数的显示。包括告警,日志等等数据都需要对应的总页数的显示。


2 对比各家定时库

2.1 TaskScheduler

TaskScheduler库只支持.net,且需要结合windows任务计划程序来调用,pass。

2.2 Fluent Scheduler

Fluent Scheduler只支持.net,pass。

2.3 Quartz.net

本身框架太重,而且使用复杂,pass。

2.4 Hangfire

相对Quartz轻量很多,使用也简单,而且有网页可以访问来观察任务执行情况,但是有一个致命的缺点就是只能支持分钟及以上的定时任务处理原因在于Hangfire用的是开源的NCrontab组件,跟linux上的crontab指令相似。在本应用中,总页数在1分钟之后更新,无法忍受。pass

2.5 Coravel

框架轻,使用简单,支持秒级定时任务。Coravel Pro可以连接数据库进行任务调度,Coravel Pro可以支持web可视化,将任务执行情况通过web显示出来。适合本应用背景。


3 Coravel的一般使用

3.1 Nuget安装

在调用类库层安装Coravel。

3.2 依赖注入

在startup.cs中的ConfigureServices方法中进行依赖注入
services.AddScheduler();

3.3 配置调度器

在startup.cs中的Configure方法中配置链两个定时任务

  var provider = app.ApplicationServices;     
  provider.UseScheduler(scheduler =>
       {//配置任务1方法
           scheduler.Schedule(() => Console.WriteLine("Every second during the week."))
           //工作日每隔1秒输出
           .EverySecond()
           .Weekday();
       });         
  provider.UseScheduler(scheduler =>
  {//配置任务2方法
      scheduler.Schedule(() => Console.WriteLine("Every 5 second during the week."))
      //工作日每隔5秒输出
      .EverySeconds(5)
      .Weekday();
  });

3.4 运行程序,观察输出

从上图结果中可以看到任务1每隔1秒打印输出;任务2每隔5秒打印输出,正确。

3.5 Cron 表达式

Coravel 支持Cron Expressions,有需要的可以根据应用场景设置Cron表达式

  • * * * * * run every minute
  • 00 13 * * * run at 1:00 pm daily
  • 00 1,2,3 * * * run at 1:00 pm, 2:00 pm and 3:00 pm daily
  • 00 1-3 * * * same as above
  • 00 /2 * * run every two hours on the hour

3.6 错误支持

Coravel 发布于2018年6月28日,才刚起步还不成熟,我在调试工作日秒级定时任务的时候会报错。
详见#91 https://github.com/jamesmh/coravel/issues/91
作者在几小时内利用工作时间,解决了问题,还发布到nuget2.5.1。很是感动。

3.7其他功能支持

此外,Coravel还支持任务队列,缓存,事件组播,邮件等。任务队列可依据读者使用情况,视情况另起一篇,缓存不建议用此组件,可用Easycache。事件组播亦不建议用此库,可参考https://www.cnblogs.com/JerryMouseLi/p/11012839.html。邮件亦不建议用此组件。

3.8 Coravel Pro

Coravel Pro可以连接数据库进行任务调度,Coravel Pro可以支持web可视化,将任务执行情况通过web显示出来。在这里不做详细介绍,有需要的读者可自行研究。


4 Coravel的松耦合使用(含总页数统计)

4.1 依赖注入自定义类

ConfigureServices中对松耦合的类Statistic进行依赖注入

 services.AddTransient<Statistic>();

4.2配置调度器

在startup.cs中的Configure方法中配置自定义松耦合任务

    var provider = app.ApplicationServices;     
    provider.UseScheduler(scheduler =>
         {
             scheduler.Schedule<Statistic>()
             .EverySecond()
             .Weekday();
         });   

4.3 编写松耦合任务的代码

详细说明,见代码注释。

using Coravel.Invocable;//需要引用此类库来进行自定义任务
using IBMS.Infrastruct.UoW;
using System;
using System.Threading.Tasks;

namespace IBMS.WEBAPI.Extension
{
    public class Statistic: IInvocable
    {
        //工作单元依赖注入
        UnitOfWork _unitOfWork;
        public Statistic(UnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }
        public  async Task Invoke()
        {
           //按每页10分页计算出来的总页数
            var IPBoxCount = _unitOfWork.IPBoxRepository.Count()/10+1;
            Console.WriteLine("Every second during the week.");
            Console.WriteLine("Count:{0}", IPBoxCount);
        }
    }
}

注意:
1.编写的任务一定要在 Invoke中,这属于固定格式;
public async Task Invoke() {}

  1. 需要引入以下库:
    using Coravel.Invocable;


    5. 结果验证

    5.1 数据库有102条数据。按每10条分一页,总页数为11页。

5.2 结果输出

从结果可以看出,定时计算出总页数11页定时1秒输出。同时可以看到EF Cor ORM最终生成的数据库语句,与我们的期望相符。

    SELECT COUNT(*)
    FROM `IPBox` AS `c`


6 小结

当然总页数的计算可以在每次查询时生成,如下

var IPBoxCount =  _unitOfWork.IPBoxRepository.Count()/10+1;
return Json(new { pageModel, IPBoxCount });

个人觉得,如果数据量小可以直接查询总数,计算总页数然后返回的方法;如果数据量很大,比如100万的数据(状态,告警,日志信息等),可能会拖慢速度,使网页变卡,则使用定时计算总页数的方法为佳。您觉得呢?不合理的地方可以留言。笔者发现在国内写Coravel的文章还没有,如果觉得本文可以,欢迎点右下角推荐,让Coravel这个优雅的工具被更多人知晓使用。


版权声明:本文为JerryMouseLi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/JerryMouseLi/p/11054546.html