前言

前段时间需要在一个新项目里添加两个后台任务,去定时请求两个供应商的API来同步数据;由于项目本身只是一个很小的服务,不太希望引入太重的框架,同时也没持久化要求;于是我开始寻找在Quartz.Net、Hangfire之外,是否还有更为轻量级的框架满足我的要求,最终我选择了Coravel.

简介

Coravel是一个专为.NET Core设计的.NET Standard库,除了任务调度,还提供了像队列、缓存、邮件等其它高级功能。特点就是对开发者十分友好,接入十分简单、优雅、流畅,接近于零配置。
作为一个生于2018年的年轻项目,后发优势明显,一开始就是基于.Net Standard 2.0实现,没有历史负担,同时又可以利用很多.Net Core新特性。

用法

首先安装Coravel包

  dotnet add package coravel

下面演示在.Net 6 Minimal API项目中接入Coravel并设置两个定时任务,是不是非常简单:)

  using Coravel;
   
  var builder = WebApplication.CreateBuilder(args);
   
  //只使用Coravel的任务调度功能
  builder.Services.AddScheduler();
   
  //注册你自己的调度任务
  builder.Services.AddTransient<YourCoravelJob1>();
  builder.Services.AddTransient<YourCoravelJob2>();
   
  var app = builder.Build();
   
  //配置任务
  app.Services.UseScheduler(scheduler =>
  {
  scheduler.Schedule<YourCoravelJob1>().EveryFiveMinutes(); //每5分钟执行一次Job1
  scheduler.Schedule<YourCoravelJob2>().Hourly().Monday(); // 每周一每小时执行一次
  });

Coravel预先定义好了很多常用的间隔频率,非常的全面,像上面用到的 EveryFiveMinutes() 和 Hourly(),是不是非常的简单优雅;当然Coravel也支持Cron表达式。

Invocable 是Coravel中的核心概念,代表一个独立的任务,上面的YourCoravelJob1和YourCoravelJob2就是 Invocable,Coravel直接调度这些Invocable
要创建你自己的Invocable,只需实现 IInvocable接口,在 Invoke方法中编码你的任务。

  public class YourCoravelJob1 : IInvocable
  {
  private readonly ILogger _logger;
   
  public YourCoravelJob1(ILogger<YourCoravelJob1> logger)
  {
  _logger = logger;
  }
   
  public async Task Invoke()
  {
  _logger.LogInformation("start..");
  }
  }
  }

原理

Coravel使用是的.Net Core 2.0引入的IHostedService来实现后台定时任务。(因此只有.Net Core 2.0以上的项目才能使用Coravel)

  public interface IHostedService
  {
  Task StartAsync(CancellationToken cancellationToken);
  Task StopAsync(CancellationToken cancellationToken);
  }

SchedulerHost即实现了IHostedService接口,在 其StartAsync方法中,当程序完全启动时,注册了一个的Timer

  public Task StartAsync(CancellationToken cancellationToken)
  {
  this._lifetime.ApplicationStarted.Register(InitializeAfterAppStarted);
  return Task.CompletedTask;
  }
   
  private void InitializeAfterAppStarted()
  {
  this._timer = new Timer(this.RunSchedulerPerSecondAsync, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
  }
   
  private async void RunSchedulerPerSecondAsync(object state)
  {
  if (this._schedulerEnabled)
  {
  await this._scheduler.RunSchedulerAsync();
  }
  }

每秒调用 RunSchedulerAsync 激活到点的Invocable,同时会根据情况将任务分组,在单独的线程分开执行。从这里可以看到Coravel是支持秒级任务的。

在 StopAsync 方法中,会先等待正在执行的任务完成才会关闭,这个功能还是比较重要。

  public async Task StopAsync(CancellationToken cancellationToken)
  {
  this._schedulerEnabled = false; // Prevents changing the timer from firing scheduled tasks.
  this._timer?.Change(Timeout.Infinite, 0);
   
  this._scheduler.CancelAllCancellableTasks();
   
  // If a previous scheduler execution is still running (due to some long-running scheduled task[s])
  // we don't want to shutdown while they are still running.
  if (this._scheduler.IsRunning)
  {
  this._logger.LogWarning(ScheduledTasksRunningMessage);
  }
   
  while (this._scheduler.IsRunning)
  {
  await Task.Delay(50);
  }
  }
   

总结

本文介绍一个对开发者友好的、轻量级、零配置的.Net Standard库Coravel,并演示了如何使用Coravel在.Net 6 Minimal API中创建定时任务,最后浅析了的实现原理。作为一个年轻的框架,Coravel站在了巨人的肩膀上,相比Quartz.Net、Hangfire,也拥有很多亮点特性,很值得尝试。

任何问题或者建议,欢迎评论区留言讨论~

参考链接

 

最新文章

  1. python处理json和redis hash的坑
  2. System.Linq.Dynamic的使用
  3. 【Win10 UWP】微信SDK基本使用方法和基本原理
  4. JS设置cookie、读取cookie、删除cookie
  5. Windows批处理以服务的方式启动解决思路(ShadowsockR注册成Windows Service)
  6. MySQL主从同步报Client requested master to start replication from position
  7. ASP.NET MVC 第七回 UrlHelper
  8. uva 10007 Count the Trees
  9. Xcode 新版本如何设置ARC
  10. python中使用ctypes调用MinGW生成的动态链接库(dll)
  11. Java中的static、final关键字
  12. 【Android开发学习笔记之一】5大布局方式详解
  13. Android 中 SearchView
  14. Echarts 中国地图(包括china.js文件)
  15. .NET Core实战项目之CMS 第十章 设计篇-系统开发框架设计
  16. DAY01、计算机组成及操作系统
  17. 初始化vue项目,报错This is probably not a problem with npm,there is likely additional logging output above
  18. linux 环境安装
  19. location匹配
  20. ASP.Net MVC(1) 之走进MVC

热门文章

  1. JQery easyUI 滚动分页
  2. Spring 的XML配置文件中提示的配置
  3. 报错:tar: This does not look like a tar archive
  4. CMMI审核期间的主要流程
  5. 【阿里云ACP】-03(数据库RDS)
  6. STM32F0 LL库IIC第二地址配置错误
  7. Navie UI
  8. K8s试验环境搭建(一)
  9. Java 04-基础 数据类型转换 自动类型转换+强制类型转换
  10. Vue2 Axios简单封装