.NET 6.0 Web API Hangfire

Hangfire 文档 
Hangfire 中文文档 
Hangfire GitHub使用示例源码 
在线Cron表达式生成器 

● Hangfire允许您以非常简单但可靠的方式在请求管道之外启动方法调用。 这种 后台线程 中执行方法的行为称为 后台任务。
● 它是由:客户端、作业存储、服务端 组成的。
● Hangfire可以在 ASP.NET Web应用程序 、非ASP.NET Web应用程序、控制台应用程序 或 Windows服务 中使用。
● 可以使用Hangfire创建任何类型的后台作业: fire-and-forget (自助调用), delayed (在一段时间后执行调用)、 recurring (按小时,每天执行方法等)
● Hangfire将后台任务及相关的其他信息保存到持久库,SQL Server,MySql,Redis,MemoryStorage

1、管理 NuGet 程序包
Hangfire.AspNetCore
Hangfire.SqlServer
Hangfire.MySql
Hangfire.MemoryStorage
Hangfire.MySqlStorage
Hangfire.PostgreSql

2、Program.cs

using Hangfire;
using Hangfire.MemoryStorage;
using Hangfire.Redis.StackExchange;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.Configuration;var builder = WebApplication.CreateBuilder(args);
var Configuration = builder.Configuration;// Add services to the container.#region Add Hangfire services.
// MemoryStorage
builder.Services.AddHangfire(configuration => configuration.UseMemoryStorage());
//builder.Services.AddHangfire(configuration => configuration.UseStorage(new MemoryStorage()));// Redis
//builder.Services.AddHangfire(x =>
//{
//    RedisStorageOptions options = new RedisStorageOptions()
//    {
//        Prefix = "hangfire:",   //键前缀
//    };
//    x.UseRedisStorage(Configuration.GetValue<string>("ConnectionStrings:Redis:ConnectionString"), options);
//});// SqlServer 方式1
//builder.Services.AddHangfire(configuration => configuration.UseSqlServerStorage(config.GetConnectionString("HangfireConnection")));// SqlServer 方式2
//builder.Services.AddHangfire(configuration => configuration
//    .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)      // 设置数据兼容级别
//    .UseSimpleAssemblyNameTypeSerializer()                          // 使用简单程序集名称类型序列化程序
//    .UseRecommendedSerializerSettings()                             // 使用推荐的序列化设置
//    .UseSqlServerStorage(config.GetValue<string>("ConnectionStrings:BaseDb:ConnectionString"), new SqlServerStorageOptions   //数据库设置
//    //.UseSqlServerStorage(config.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions
//    {
//        TransactionIsolationLevel = IsolationLevel.ReadCommitted,   // 事务隔离级别。默认值为读提交。
//        TransactionTimeout = TimeSpan.FromMinutes(1),               // 事务超时。默认为1分钟
//        JobExpirationCheckInterval = TimeSpan.FromHours(1),         // 作业过期检查间隔(管理过期记录)。默认为1小时
//        CountersAggregateInterval = TimeSpan.FromMinutes(5),        // 间隔到聚合计数器。默认为5分钟
//        PrepareSchemaIfNecessary = true,                            // 如果设置为true,则创建数据库表。默认值为true
//        CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),           // 命令批处理最大超时时间
//        SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),       // 滑动超时时间
//        QueuePollInterval = TimeSpan.Zero,                          // 作业队列轮询间隔。默认值为15秒
//        UseRecommendedIsolationLevel = true,                        // 是否使用建议的隔离级别
//        DisableGlobalLocks = true,                                  // 是否禁用全局锁,需要迁移到模式7
//        DashboardJobListLimit = 50000,                              // 仪表板作业列表上限。默认值为50000 
//    }));// Add the processing server as IHostedService
builder.Services.AddHangfireServer();
#endregionbuilder.Services.AddControllers();var app = builder.Build();// Configure the HTTP request pipeline.//Hangfire 仪表盘
//访问地址 http://localhost:5000/hangfire
app.UseHangfireDashboard();app.UseAuthorization();#region Hangfire// 基于队列的任务处理
var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("即时任务!"));// 延迟任务执行
var jobId2 = BackgroundJob.Schedule(() => Console.WriteLine("延迟任务!"), TimeSpan.FromMilliseconds(10));// 循环任务执行,最小单位是分钟,可以自定义复杂模式
//RecurringJob.AddOrUpdate("myrecurringjob", () => Console.WriteLine("重复任务!"), Cron.Minutely);
RecurringJob.AddOrUpdate("myrecurringjob", () => Console.Write("重复任务,每1分钟执行任务"), "0 0/1 * * * ?");// 延续性任务执行,在第一个任务执行完之后紧接着再次执行另外的任务
BackgroundJob.ContinueJobWith(jobId2, () => Console.WriteLine("jobId2执行完了再继续执行!"));using (var server = new BackgroundJobServer())
{BackgroundJob.Enqueue(() => Console.WriteLine("Simple111"));
}#endregionapp.MapControllers();#region Hangfire
app.Map("/index", r =>
{r.Run(async context =>{//任务每分钟执行一次RecurringJob.AddOrUpdate(() => Console.WriteLine($"ASP.NET Core LineZero"), Cron.Minutely());await context.Response.WriteAsync("ok");});
});app.Map("/one", r =>
{r.Run(context =>{//任务执行一次BackgroundJob.Enqueue(() => Console.WriteLine($"ASP.NET Core One Start LineZero{DateTime.Now}"));return context.Response.WriteAsync("ok");});
});app.Map("/await", r =>
{r.Run(context =>{//任务延时两分钟执行BackgroundJob.Schedule(() => Console.WriteLine($"ASP.NET Core await LineZero{DateTime.Now}"), TimeSpan.FromMinutes(2));return context.Response.WriteAsync("ok");});
});
#endregion
app.Run();

3、CustomJobController.cs

using Hangfire.Server;
using Hangfire;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;namespace Web.Controllers
{[Route("api/[controller]")][ApiController]public class CustomJobController : ControllerBase{private readonly ILogger _logger;private readonly IBackgroundJobClient _backgroundJobClient;public CustomJobController(ILogger<CustomJobController> logger, IBackgroundJobClient backgroundJobClient){_logger = logger;_backgroundJobClient = backgroundJobClient;}[HttpGet]public IActionResult Get(){var jobId = _backgroundJobClient.Enqueue(() => FireAndForgetJob(null));Thread.Sleep(5000);return Ok($"Job Id: {jobId} completed...");}[HttpGet]public IActionResult Get1(){var jobId = BackgroundJob.Schedule(() => Console.WriteLine("This is an example of a delayed job"), TimeSpan.FromDays(1));return Ok($"Job Id: {jobId} completed...");}[HttpGet]public IActionResult Get2(){var jobId = _backgroundJobClient.Enqueue(() => FireAndForgetJob(null));Thread.Sleep(5000);return Ok($"Job Id: {jobId} completed...");}public Task FireAndForgetJob(PerformContext context){var jobId = context.BackgroundJob.Id;_logger.LogInformation($"Executing Job Id: {jobId}...");return Task.CompletedTask;}}
}

4、Cron 表达式
是一个时间表达式,包含6或7个字段组成,每个字段代表不同的时间单位,前6个字段是必须的,最后一个【年】是可选的,从左到右依次为
7个字段:秒 分 时 日 月 星期 年
6个字段:秒 分 时 日 月 星期 (年可为空)
其中年可为空,不是必须;     

在大部分使用cron的场景下, - * / ? 这几个常用字符就可以满足我们的需求了。
【*】:每的意思。在不同的字段上,就代表每秒,每分,每小时等。
【-】:指定值的范围。比如[1-10],在秒字段里就是每分钟的第1到10秒,在分就是每小时的第1到10分钟,以此类推。
【,】:指定某几个值。比如[2,4,5],在秒字段里就是每分钟的第2,第4,第5秒,以此类推。
【/】:指定值的起始和增加幅度。比如[3/5],在秒字段就是每分钟的第3秒开始,每隔5秒生效一次,也就是第3秒、8秒、13秒,以此类推。
【?】:仅用于【日】和【周】字段。因为在指定某日和周几的时候,这两个值实际上是冲突的,所以需要用【?】标识不生效的字段。比如【0 1 * * * ?】就代表每年每月每日每小时的1分0秒触发任务。这里的周就没有效果了。
*
分钟字段,表示程序应该在哪些分钟运行
星号(*):表示每隔1分钟触发
逗号(,):用于指定多个分钟,例如【0,15,30,45】表示每小时的0、15、30和45分钟
中划线(-):用于指定一个时间段,例如:【10-20】表示从10分钟到20分钟
斜杠(/):用于指定一个时间间隔,例如:【*/5】表示每5分钟
*
示例:
0 0/5 * * * *:每5分钟运行程序
0 10,20 * * * *:在每个小时的10和20分钟运行程序
0 10-20/5 * * * *:在每个小时的10到20分钟之间每5分钟运行程序
*
小时字段表示程序应该在哪些小时运行
- 星号(*):表示所有小时
- 逗号(,):用于指定多个小时,例如:——0,12,18——表示每天的0、12、18点
- 中划线(-):用于指定一个时间段,例如:——9-17——表示从9点到17点
- 斜杠(/):用于指定一个时间间隔,例如:——*/2——表示每2小时
*
示例:
0 0 */2 * * *:每2小时运行程序
0 9-17 * * * *:在每天的9点到17点之间运行程序
0 0-12/3 * * * *:在每天的0点到12点之间每3小时运行程序
*
经典案例:
"5 * * * * ?"   每分钟的第5秒执行一次
"30 * * * * ?" 每分钟的第30秒触发任务
"30 10 * * * ?" 每小时的10分30秒触发任务
"30 10 1 * * ?" 每天1点10分30秒触发任务
"30 10 1 20 * ?" 每月20号1点10分30秒触发任务
"30 10 1 20 10 ? *" 每年10月20号1点10分30秒触发任务
"30 10 1 20 10 ? 2011" 2011年10月20号1点10分30秒触发任务
"30 10 1 ? 10 * 2011" 2011年10月每天1点10分30秒触发任务
"30 10 1 ? 10 SUN 2011" 2011年10月每周日1点10分30秒触发任务
"15,30,45 * * * * ?" 每15秒,30秒,45秒时触发任务
"15-45 * * * * ?" 15到45秒内,每秒都触发任务
"15/5 * * * * ?" 每分钟的每15秒开始触发,每隔5秒触发一次
"15-30/5 * * * * ?" 每分钟的15秒到30秒之间开始触发,每隔5秒触发一次
"0 0/3 * * * ?" 每小时的第0分0秒开始,每三分钟触发一次
"0 15 10 ? * MON-FRI" 星期一到星期五的10点15分0秒触发任务
"0 15 10 L * ?" 每个月最后一天的10点15分0秒触发任务
"0 15 10 LW * ?" 每个月最后一个工作日的10点15分0秒触发任务
"0 15 10 ? * 5L" 每个月最后一个星期四的10点15分0秒触发任务
"0 15 10 ? * 5#3" 每个月第三周的星期四的10点15分0秒触发任务

常用cron表达式例子 
(1)0/2 * * * * ?   表示每2秒 执行任务
(1)0 0/2 * * * ?    表示每2分钟 执行任务
(1)0 0 2 1 * ?   表示在每月的1日的凌晨2点调整任务
(2)0 15 10 ? * MON-FRI   表示周一到周五每天上午10:15执行作业
(3)0 15 10 ? 6L 2002-2006   表示2002-2006年的每个月的最后一个星期五上午10:15执行作
(4)0 0 10,14,16 * * ?   每天上午10点,下午2点,4点 
(5)0 0/30 9-17 * * ?   朝九晚五工作时间内每半小时 
(6)0 0 12 ? * WED    表示每个星期三中午12点 
(7)0 0 12 * * ?   每天中午12点触发 
(8)0 15 10 ? * *    每天上午10:15触发 
(9)0 15 10 * * ?     每天上午10:15触发 
(10)0 15 10 * * ?    每天上午10:15触发 
(11)0 15 10 * * ? 2005    2005年的每天上午10:15触发 
(12)0 * 14 * * ?     在每天下午2点到下午2:59期间的每1分钟触发 
(13)0 0/5 14 * * ?    在每天下午2点到下午2:55期间的每5分钟触发 
(14)0 0/5 14,18 * * ?     在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 
(15)0 0-5 14 * * ?    在每天下午2点到下午2:05期间的每1分钟触发 
(16)0 10,44 14 ? 3 WED    每年三月的星期三的下午2:10和2:44触发 
(17)0 15 10 ? * MON-FRI    周一至周五的上午10:15触发 
(18)0 15 10 15 * ?    每月15日上午10:15触发 
(19)0 15 10 L * ?    每月最后一日的上午10:15触发 
(20)0 15 10 ? * 6L    每月的最后一个星期五上午10:15触发 
(21)0 15 10 ? * 6L 2002-2005   2002年至2005年的每月的最后一个星期五上午10:15触发 
(22)0 15 10 ? * 6#3   每月的第三个星期五上午10:15触发
*
*
*

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/164774.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全波形反演培训的思考与总结

一. InversionNet 最简单的端到端DL_FWI 1. 网络结构&#xff1a; 图1 构建了一个具有编码器-解码器结构的卷积神经网络&#xff0c;根据地震波动数据模拟地下速度结构。编码器主要由卷积层构建&#xff0c;它从输入地震数据中提取高级特征并将其压缩为单个高维向量。解码器然后…

谷歌云:下一代开发者和企业解决方案的强力竞争者

自从2018年Oracle前研发总裁Thomas Kurian加入谷歌云&#xff08;Google Cloud&#xff09;并出任谷歌云CEO以来&#xff0c;业界对于谷歌云的发展就十分好奇。而谷歌云的前任CEO Diane Greene曾是VMware的创始人之一&#xff0c;那么两任企业级技术和解决方案出身的CEO&#x…

代码随想录算法训练营第五十五天 | 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

300.最长递增子序列 视频讲解&#xff1a;动态规划之子序列问题&#xff0c;元素不连续&#xff01;| LeetCode&#xff1a;300.最长递增子序列_哔哩哔哩_bilibili 代码随想录 &#xff08;1&#xff09;代码 674. 最长连续递增序列 视频讲解&#xff1a;动态规划之子序列问题…

前端学成在线项目详细解析一

学成在线项目 01-项目目录 网站根目录是指存放网站的第一层文件夹&#xff0c;内部包含当前网站的所有素材&#xff0c;包含 HTML、CSS、图片、JavaScript等等。 首页引入CSS文件 <!-- 顺序要求&#xff1a;先清除再设置 --> <link rel"stylesheet" hre…

Vue非单文件组件

组件就是用来实现局部特定功能效果的代码集合&#xff0c;为的就是复用编码&#xff0c;简化项目编码&#xff0c;提高运行效率。 组件分为非单文件组件和单文件组件&#xff0c;这里介绍的是非单文件组件。 一、创建组件 创建组件的语法格式如下&#xff1a; const 组件名 …

微信小程序开发之自定义组件(会议OA项目其他页面搭建)

目录 前言 一、WeChat中的自定义组件 1. 基本概述 2. 包含文件及作用 3. 自定义组件的作用 4.使用步骤&#xff1a; 二、tabs组件及会议管理布局 tabs组件 1. 创建组件 准备 创建 使用组件 会议管理布局 tabs.wxml指定组件模版 tabs.wxss完成样式设计 tabs.js定义属…

柔性数组的使用及注意事项

1.柔性数组在结构体当中,并且在结构体的最后面. 2.结构体中除了柔型数组外至少还要有一个其他成员. 3.sizeof()返回结构体的大小不包含柔性数组的大小. 4.malloc 例:struct sdshdr16 *p malloc(sizeof (struct sdshdr16) 32); // 32 为柔性数组的大小 5.free 例: fre…

讲解 CSS 过渡和动画 — transition/animation (很全面)

前言 由于用户越来越注重 Web应用 的使用体验&#xff0c;随之而来的是 Web应用 需要提供了更加完善的 Web 动画 效果来实现以平滑的状态贯穿于用户的整个使用过程中。现在&#xff0c;这已经是司空见惯了&#xff0c;用户潜意识是希望可以获得更快的反馈响应和更友好的用户界…

Python用selenium实现自动登录和下单的项目实战

本文主要介绍了Python用selenium实现自动登录和下单的项目实战&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧− 前言 学python对selenium应该不陌生吧 Selenium…

轻量级导出 Excel 标准格式

一般业务系统中都有导出到 Excel 功能&#xff0c;其实质就是把数据库里面一条条记录转换到 Excel 文件上。Java 常用的第三方类库有 Apache POI 和阿里巴巴开源的 EasyExcel 等。另外也有通过 Web 模板技术渲染 Excel 文件导出&#xff0c;这实质是 MVC 模式的延伸&#xff0c…

基于epoll封装非阻塞的reactor框架(附源码)

C++常用功能源码系列 文章目录 C++常用功能源码系列前言一、reactor架构二、client端reactor代码三、server端reactor代码四、单reactor架构可以实现百万并发总结前言 本文是C/C++常用功能代码封装专栏的导航贴。部分来源于实战项目中的部分功能提炼,希望能够达到你在自己的项…

Atlassian Confluence OGNL表达式注入RCE CVE-2021-26084

影响版本 All 4.x.x versions All 5.x.x versions All 6.0.x versions All 6.1.x versions All 6.2.x versions All 6.3.x versions All 6.4.x versions All 6.5.x versions All 6.6.x versions All 6.7.x versions All 6.8.x versions All 6.9.x versions All 6.1…

P1664 每日打卡心情好 题解

文章目录 题目背景题目描述输入格式输出格式样例样例输入样例输出 数据范围与提示思路及部分实现完整代码文章小结 题目背景 在洛谷中&#xff0c;打卡不只是一个简单的鼠标点击动作&#xff0c;通过每天在洛谷打卡&#xff0c;可以清晰地记录下自己在洛谷学习的足迹。通过每天…

Python数据挖掘实用案例——自动售货机销售数据分析与应用

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前学习C/C、算法、Python、Java等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&…

瑞芯微RKNN开发·yolov5

官方预训练模型转换 下载yolov5-v6.0分支源码解压到本地&#xff0c;并配置基础运行环境。下载官方预训练模型 yolov5n.ptyolov5s.ptyolov5m.pt… 进入yolov5-6.0目录下&#xff0c;新建文件夹weights&#xff0c;并将步骤2中下载的权重文件放进去。修改models/yolo.py文件 …

汽车安全的未来:毫米波雷达在碰撞避免系统中的角色

随着科技的飞速发展&#xff0c;汽车安全系统变得愈加智能化&#xff0c;而毫米波雷达技术正是这一领域的亮点之一。本文将深入探讨毫米波雷达在汽车碰撞避免系统中的关键角色&#xff0c;以及其对未来汽车安全的影响。 随着城市交通的拥堵和驾驶环境的变化&#xff0c;汽车安全…

Cannot use object of type __PHP_Incomplete_Class as array

场景&#xff1a;将项目复制 出来一份后&#xff0c;修改控制器&#xff0c;打开后就报错 解决&#xff1a;将runtime 清除后就正常了

jenkins 原理篇——pipeline流水线 声明式语法详解

大家好&#xff0c;我是蓝胖子&#xff0c;相信大家平时项目中或多或少都有用到jenkins&#xff0c;它的piepeline模式能够对项目的发布流程进行编排&#xff0c;优化部署效率&#xff0c;减少错误的发生&#xff0c;如何去写一个pipeline脚本呢&#xff0c;今天我们就来简单看…

手写一个PrattParser基本运算解析器3: 基于Swift的PrattParser的项目概述

点击查看 基于Swift的PrattParser项目 PrattParser项目概述 前段时间一直想着手恶补 编译原理 的相关知识, 一开始打算直接读大学的 编译原理, 虽然内容丰富, 但是着实抽象难懂. 无意间看到B站的熊爷关于普拉特解析器相关内容, 感觉是一个非常好的切入点.所以就写了基于Swift版…

软考系列(系统架构师)- 2018年系统架构师软考案例分析考点

试题一 软件架构&#xff08;非功能性需求、C/S 架构&#xff09; 【问题1】&#xff08;8分&#xff09; 在系统架构设计中&#xff0c;决定系统架构设计的非功能性需求主要有四类&#xff1a;操作性需求、性能需求、安全性需求和文化需求。请简要说明四类需求的含义。 (1) …