与quartz.net对比

Quartz.net在定时任务处理方面优势如下:

  • 支持秒级单位的定时任务处理,但是Hangfire只能支持分钟及以上的定时任务处理

原因在于Hangfire用的是开源的NCrontab组件,跟linux上的crontab指令相似。

  • 更加复杂的触发器,日历以及任务调度处理
  • 可配置的定时任务

但是为什么要换Hangfire? 很大的原因在于项目需要一个后台可监控的应用,不用每次都要从服务器拉取日志查看,在没有ELK的时候相当不方便。Hangfire控制面板不仅提供监控,也可以手动的触发执行定时任务。如果在定时任务处理方面没有很高的要求,比如一定要5s定时执行,Hangfire值得拥有。抛开这些,Hangfire优势太明显了:

  • 持久化保存任务、队列、统计信息
  • 重试机制
  • 多语言支持
  • 支持任务取消
  • 支持按指定Job Queue处理任务
  • 服务器端工作线程可控,即job执行并发数控制
  • 分布式部署,支持高可用
  • 良好的扩展性,如支持IOC、Hangfire Dashboard授权控制、Asp.net Core、持久化存储等

这里演示在asp.net core使用Redis作为Hangfire的持久化存储

使用

1、引用包

Hangfire.AspNetCore

Hangfire.Redis.StackExchange

2、注入hangfire及配置

这里说明下 services.AddHostedService();是定时任务,继承自BackgroundService。


然后在configure中引入hangfire。如果在这里不引入队列的名字,会导致添加的任务无法加入到队列。

app.UseHangfireDashboard();表示使用看板功能。

3、普通使用,比如添加任务到队列或者添加延时任务,基本是一样的。

这里在接口中直接演示,直接使用BackgroundJob.Enqueue将方法添加到队列。

注意队列名称要使用小写,被添加到队列中的方法需要是Public的。

4、定时任务

定义定时任务配置类

/// <summary>/// 工作任务配置/// </summary>public class WorkerConfig{/// <summary>/// 轮询秒数/// </summary>public int IntervalSecond { get; set; }/// <summary>/// 工作唯一编号/// </summary>public string WorkerId { get; set; }/// <summary>/// 队列名称/// </summary>public string QueuesName { get; set; }/// <summary>/// 表达式/// </summary>public string Cron { get; set; }}

定义需要定时执行的接口方法

/// <summary>/// 所有的后台工作者类都应实现该接口/// </summary>public interface IBackgroundWorkerDo{/// <summary>/// 执行具体的任务/// </summary>/// <param name="context"></param>/// <returns></returns>Task DoWorkAsync(PerformContext context);}

定义hangfire基类,定时任务的类都继承该类。

public abstract class HangfireWorkerPxoxy:BackgroundService{private readonly IConfiguration _appConfiguration;private readonly WorkerConfig _config;public HangfireWorkerPxoxy(IConfiguration appConfiguration, WorkerConfig Config){_appConfiguration = appConfiguration;_config = Config;}public void Excete<T>() where T : IBackgroundWorkerDo{var appsetting = _appConfiguration.GetSection("Appsetting").Get<Appsetting>();var options = new RedisStorageOptions{Db = appsetting.RedisConfig.Defaultdatabase,SucceededListSize = 50000,DeletedListSize = 50000,ExpiryCheckInterval = TimeSpan.FromHours(1),InvisibilityTimeout = TimeSpan.FromHours(3)};var redisString = appsetting.RedisConfig.HostName + ":" + appsetting.RedisConfig.Port + ",defaultdatabase="+ appsetting.RedisConfig.Defaultdatabase;JobStorage.Current = new RedisStorage(redisString);var manager = new RecurringJobManager(JobStorage.Current);string workerId = _config.WorkerId;string cron = string.IsNullOrEmpty(_config.Cron) ? Cron.MinuteInterval(_config.IntervalSecond / 60) : _config.Cron;manager.RemoveIfExists(workerId);manager.AddOrUpdate(workerId, Job.FromExpression<T>((t) => t.DoWorkAsync(null)), cron, TimeZoneInfo.Local, string.IsNullOrEmpty(_config.QueuesName) ? "default" : _config.QueuesName);}

定义最终的定时任务类

/// <summary>///  定时任务/// </summary>class MyJob1 : HangfireWorkerPxoxy,IBackgroundWorkerDo{private readonly ILogger _logger;public MyJob1(IConfiguration _appConfiguration, ILogger<MyJob1> logger) : base(_appConfiguration, new WorkerConfig { IntervalSecond = 60 * 1, WorkerId = "RealWorker", QueuesName = "queue1" }){_logger = logger;}/// <summary>///  添加同步sku库存任务/// </summary>public  async Task DoWorkAsync(PerformContext context){var temp = await Task.FromResult(0);if (context == null){return ;}_logger.LogInformation($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 开始添加同步数据任务 ...");Thread.Sleep(1000*10);_logger.LogInformation($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 结束添加同步数据任务 ...");}protected override async Task ExecuteAsync(CancellationToken stoppingToken){var temp= await Task.FromResult(0);Excete<MyJob1>();}}

注入定时任务类,services.AddHostedService();

最后看下效果。

【.NET Core】 hangfire相关推荐

  1. 【JAVA Core】精品面试题100道

    [JAVA Core]精品面试题100道 加个说明:我的初心是Java每个技术栈整理个100道面试题,现在的底子是哪吒的<208道面试题> 后续我会把自己有价值的题和面试真题添加进入,也对 ...

  2. 【HMS Core】华为登录后返回错误码 8 、账号服务如何授权、推送服务端获取用户信息异常

    1.[HMS core][游戏登陆][问题描述] 调用华为登录后返回错误码 8 [解决方案] 错误码8的话一般在定义为内部错误(引起该错误码的原因很多),但是一般重试基本可以解决该问题(错误码).如果 ...

  3. 【.Net Core】007Http请求

    文章目录 简单的Get请求 常见的StateCode状态码 StateCode状态码的默认函数 内容协商 简单的Get请求 public class TouristRoutesController : ...

  4. 【HMS core】【Wallet Kit】【解决方案】华为钱包的客户端示例代码为何无法运行

    [问题描述] 在华为开发者联盟官方文档上下载的华为钱包(Wallet Kit)的客户端示例代码,导入到Android Studio中无法运行,下面跟着我一起来看一看究竟是怎么回事吧! 首先我们找到华为 ...

  5. 【HMS Core】【FAQ】【Health Kit】集成运动健康服务过程中,遇到一些小问题,今天分享给大家(华为手表、手环+运动健康服务问题合集)

    1.[问题描述] 如果App在专网环境下使用,无法访问互联网,这样的场景下可以直接读取到华为手表所测量的心率.血氧.睡眠数据吗? [解决方案] 至少需要能访问华为health kit 相关的服务器,否 ...

  6. 【HMS Core】Health Kit如何获取跑步锻炼记录的轨迹记录?

    [问题描述] 使用接口,"/healthkit/v1/activityRecords",可以正常获取跑步记录,但是里面没有附带轨迹数据,应该怎么获取每条记录的轨迹记录数据呢? [解 ...

  7. 【HMS core】【FAQ】In-App Purchases 常见问题分享

    1.华为支付 订阅产品,用户在支付宝内取消连续扣费后,服务端未收到取消订阅通知. [问题描述] 华为支付 订阅产品,用户在支付宝内取消连续扣费后,服务端未收到取消订阅通知. 参考订阅关键事件通知文档 ...

  8. 【HMS Core】【FAQ】【Health Kit】运动健康服务常见错误码合集 403、401、1001、20023

    1.创建数据采集器接口报错 403 [问题原因] 未在联盟官网申请相应的读写权限 [解决方案] 1.在联盟官网申请相应的读写权限 2.申请写权限后,再创建采集器 文档中心 2.读取数据时结果显示 40 ...

  9. 【.Net core】EFCore——Code First生成数据库与表

    Code First--领域设计模式中非常有用.使用 Code First 模式,专注于领域设计,创建领域类,然后生成数据库. 1.创建数据模型类 一般就是数据库里面有哪些表,就创建哪些模型, POC ...

最新文章

  1. 什么时候使用Java的@Override注释,为什么?
  2. STP、RSTP、MSTP
  3. 程序员微信头像_这才是程序员的内心独白
  4. 入门Java要学习的一些基本和高级工具
  5. python类与对象示意图_2020Python作业——类与对象,
  6. SAP Cloud SDK for JavaScript 的搭建和使用方法介绍
  7. activiti api文档_【白银人机】Activiti 工作流从入门到入土:完整 hello world 大比拼(API 结合实例讲解)...
  8. 华为薪资等级结构表_华为21级程序员月薪曝光:月薪27w,什么概念!程序员中的战斗机...
  9. dedemonkey下载_android压力测试命令monkey详解
  10. Java基础之字符如何截取?
  11. menuStrip1动态添加菜单及快捷键
  12. Oracle新建用户及权限
  13. AUTOCAD——线宽设置
  14. html以鼠标为中心放大网页,鼠标滚轮网页放大缩小
  15. html表格一行设置颜色,更改表格中一行的颜色,html
  16. 马达调速器,直流马达调速器,直流调速器
  17. Linux系列:给网卡添加IP地址方法
  18. Python格式化字符串的4种方式
  19. typescript 中 any 和 unknow 区别
  20. 74LS139改3―8线译码器_数字译码器

热门文章

  1. LCD驱动---LVDS详解(一)
  2. jsf取js变量_JSF页面中的JS取得受管bean的数据(受管bean发送数据到页面)
  3. java 中常用框架、intell idea简单使用、爬虫系统
  4. 不错的大数据课程体系(感谢某机构,希望不属于侵权)
  5. 完全限定域名(fully qualified domain name,FQDN,笔记)
  6. 预警神器来了,天翼大喇叭发出河道防汛强音
  7. php 单笔转账到支付宝账户,php实现单笔转账到支付宝功能
  8. golang操作mongo
  9. 知乎python练手的_Python新手应该如何练手?知乎5600赞答案告诉你!
  10. 2017年山东省第八届ACM程序设计竞赛总结