1、HangFire简介

  HangFire是一个免费简单实用的分布式后台定时调度服务,在现在.net开发中,人气算是很高的。

  HangFire提供了内置集成化的控制台,可以直观明了的查看作业调度情况,并且Hangfire不需要依赖于单独的应用程序执行,支持持久性存储,默认使用sqlserver。

  2、HangFire安装

  一般的,我们都是使用nuget安装HangFire  

    Install-Package Hangfire

  个人不建议这么安装,最好是根据自己的需求来,因为Hangfire默认使用SqlServer作为存储数据库,如果我们使用mysql,就没有必要了,而且最新的Hangfire会依赖于Hangfire.AspNetCore,方便在.net core项目中使用,本文以mysql作为数据库来介绍,如果我们用的是.net core项目,安装

    Install-Package Hangfire.AspNetCore
Install-Package Hangfire.MySql.Core

  如果是控制台程序,安装

    Install-Package Hangfire.MySql.Core

  3、HangFire例子

    using Hangfire;
using Hangfire.MySql.Core;
using System;
using System.Threading; namespace HangFire
{
class Program
{
static void Main(string[] args)
{
//创建表
var storage = new MySqlStorage("Server=192.168.220.129;port=3306;Database=hangfire;User ID=root;Password=123456;charset=utf8;Allow User Variables=true");
//使用mysql
GlobalConfiguration.Configuration.UseStorage(storage); //添加循环执行的定时任务
RecurringJob.AddOrUpdate(() => Console.WriteLine("Hangfire AddOrUpdate任务"), "1/5 * * * * *", TimeZoneInfo.Local, "queue1");
//后台调度任务
BackgroundJobServer jobServer = new BackgroundJobServer(new BackgroundJobServerOptions()
{
Queues = new string[] { "queue1", "queue2" },
ServerName = "Test",
WorkerCount = 1
}, storage);
//等待退出
       //jobServer.WaitForShutdownAsync(CancellationToken.None); Console.ReadLine();
}
}
}

  4、HangFire调度用法

  BackgroundJobServer用于启动调度,如上面的例子,  

    BackgroundJobServer jobServer = new BackgroundJobServer(new BackgroundJobServerOptions()
{
Queues = new string[] { "queue1", "queue2" },
ServerName = "Test",
WorkerCount = 1
}, storage);

  需要注意的是Queues参数,它是BackgroundJobServer会调度的队列,默认队列名是default,上面的例子中没有将default添加到队列中去,因此所有使用default默认队列的任务将不会被调度执行,所以建议将default也加进入,即Queues = new string[] { "default", "queue1", "queue2" }。

  重点说的是BackgroundJob和RecurringJob两个类,这两个类都是进行调度任务的操作

  BackgroundJob

  BackgroundJob主要用于单次任务的调度

    //添加任务到队列,会返回任务Id
BackgroundJob.Enqueue(() => Console.WriteLine("Hangfire Enqueue任务"));
//支持异步
BackgroundJob.Enqueue(() => MyTask.LogAsync());
//计划执行,即在指定的时间执行
BackgroundJob.Schedule(() => Console.WriteLine("Hangfire Schedule任务"), TimeSpan.FromSeconds(10));//延迟10秒后执行
//支持异步
BackgroundJob.Schedule(() => MyTask.LogAsync(), TimeSpan.FromSeconds(10));//延迟10秒后执行

  其中MyTask是一个类  

    public class MyTask
{
public static async Task LogAsync()
{
await Task.Run(() => Console.WriteLine("MyTask"));
}
}

  Enqueue用于将任务立即添加到执行队列等待执行,Schedule用于延迟添加,即延迟指定时间后将任务添加到执行度列。要注意是,这里是添加到默认队列,也就是default队列,如果在启动server时,未添加default队列,那么将不会被调度执行。而且添加的任务只会被执行一次,另外,这里只是将任务加入到默认队列中,执行还需要排队。Enqueue还有一个返回值,即jobId,它表示添加任务得到的任务Id,我们可以通过这个jobId对队列进行移除,重新进入队列等等操作。  

    //添加任务到队列,返回任务Id
var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("Hangfire Enqueue任务"));
//指定任务成功执行完再执行,同样返回新增的任务Id
var otherJobId = BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine("Hangfire ContinueJobWith任务"));
//移除
BackgroundJob.Delete(otherJobId);
//重新进入队列
BackgroundJob.Requeue(otherJobId);

  RecurringJob

  RecurringJob主要用于定时循环的任务调度  

    //添加循环执行的定时任务
RecurringJob.AddOrUpdate(() => Console.WriteLine("Hangfire AddOrUpdate任务"), "*/5 * * * * *", TimeZoneInfo.Local, "queue1");
//添加循环执行的定时任务,同时执行recurringJobId
RecurringJob.AddOrUpdate("myRecurringJobId", () => Console.WriteLine("Hangfire AddOrUpdate任务"), "*/5 * * * * *", TimeZoneInfo.Local, "queue1");

  这里说下recurringJobId,其实这个就是这个定时任务的名称,AddOrUpdate就是根据这个recurringJobId来判断是新增还是更新的,如果不指定recurringJobId,则会自动根据Lambda表达式来生成一个recurringJobId,比如上面会用Console.WriteLine作为recurringJobId,这个recurringJobId还可以用于移除任务和立即触发:  

    //移除任务
RecurringJob.RemoveIfExists("myRecurringJobId");
//立即触发一次
RecurringJob.Trigger("myRecurringJobId");

  RecurringJob采用Cron表达式来指明调度时间,这个也是Hangfire的一个优势。

  另外提一点,BackgroundJob的Enqueue方法和Schedule方法,RecurringJob的AddOrUpdate方法都有一个泛型的重载,上面的例子都是静态方法,无需调用对象,而这个泛型其实就是任务的调用对象,如:  

    BackgroundJob.Enqueue<TestModel>(tm => tm.Show());

  其中TestModel是  

    public class TestModel
{
public string Text { get; set; } = "Test"; public void Show()
{
Console.WriteLine(Text);
}
}

  默认情况下,任务的调用实例是JobActivator对象创建的,默认创建方式就是  

    public virtual object ActivateJob(Type jobType)
{
return Activator.CreateInstance(jobType);
}

  因此,这个调用对象必须是有空构造函数,否则,我们需要使用继承去重写JobActivator的ActivateJob方法,再使用GlobalConfiguration.Configuration.UseActivator();方法将重写的JobActivator集成进去,这种方式也可以用于IOC容器的支持。

  5、.net core 使用HangFire

  .net core使用hangfire很简单,首先安装Hangfire.AspNetCore和Hangfire.MySql.Core,然后在Startup中集成即可  

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hangfire.MySql.Core;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; namespace Hangfire.Web
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//添加Hangfire服务
var storage = new MySqlStorage("Server=192.168.220.129;port=3306;Database=hangfire;User ID=root;Password=123456;charset=utf8;Allow User Variables=true");
services.AddHangfire(cfg =>
{
cfg.UseStorage(storage);
});
//以IHostedService的形式启动BackgroundJobServer
//如果这里添加了,那么Configure方法中就无需调用app.UseHangfireServer();
//services.AddHangfireServer(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
} //配置后台仪表盘
app.UseHangfireDashboard();
//开始使用Hangfire服务
//如果这里添加了中间件,那么ConfigureServices中就无需调用services.AddHangfireServer();
app.UseHangfireServer(); app.UseHttpsRedirection();
app.UseMvc();
}
}
}

  然后启动之后,可以在浏览器输入http://localhost:5000/hangfire打开Hangfire的仪表盘

   

  

Hangfire任务调度框架使用的更多相关文章

  1. 开源的.NET任务调度框架-HangFire

    什么是Hangfire Hangfire 是一个开源的.NET任务调度框架,目前1.6+版本已支持.NET Core.内置提供集成化的控制台,方便后台查看及监控: 另外,Hangfire包含三大核心组 ...

  2. .NET Core下开源任务调度框架Hangfire的Api任务拓展(支持秒级任务)

    HangFire的拓展和使用 看了很多博客,小白第一次写博客. 最近由于之前的任务调度框架总出现问题,因此想寻找一个替代品,之前使用的是Quartz.Net,这个框架方便之处就是支持cron表达式适合 ...

  3. 任务调度框架Hangfire 简介

    任务调度是我们项目中常见的功能,虽然任务调度的功能实现本身并不难,但一个好用的轮子还是可以给我们的开发的效率提升不少的. 在.net环境中,较为有名的任务调度框架是HangFire与Quartz.NE ...

  4. .NET Core下开源任务调度框架Hangfire

    今天无意中发现了一个很好用的任务调度框架.Hangfire作为一款高人气且容易上手的分布式后台执行服务,支持多种数据库.在 .net core的环境中,由Core自带的DI管理着生命周期. 相较于qu ...

  5. 任务调度框架FluentScheduler简介

    之前我在文章中介绍过.net中的任务调度框架Hangfire,HangFire虽然本身输入比较简单好用的,但是,如果我们的程序本身提供的服务不是任务调度,而任务调度只是里面并不重要的小功能的时候,用H ...

  6. 【niubi-job——一个分布式的任务调度框架】----niubi-job这下更牛逼了!

    niubi-job迎来第一次重大优化 niubi-job是一款专门针对定时任务所设计的分布式任务调度框架,它可以进行动态发布任务,并且有超高的可用性保证. 有多少人半夜被叫起来查BUG,结果差到最后发 ...

  7. 【niubi-job——一个分布式的任务调度框架】----安装教程

    niubi-job是什么 niubi-job是LZ耗时三个星期,费尽心血打造的一个具备高可靠性以及水平扩展能力的分布式任务调度框架,采用quartz作为底层的任务调度管理器,zookeeper做集群的 ...

  8. Quarzt.NET 任务调度框架

      Quartz.NET是一个开源的作业调度框架,是 OpenSymphony 的 Quartz API 的.NET移植,它用C#写成,可用于winform和asp.net应用中.它提供了巨大的灵活性 ...

  9. Quartz.Net任务调度框架

    Quartz.Net是一个开源的任务调度框架,非常强大,能够通过简单的配置帮助我们定时具体的操作. 相对于我们用的线程里面while(true)然后sleep来执行某个操作,应该算的上是高端,大气,上 ...

随机推荐

  1. spring注解-组件注册

    一.@Configuration+@Bean @Configuration:配置类==配置文件 @Bean:给容器中注册一个Bean:类型为返回值的类型,默认是用方法名作为id @Bean(" ...

  2. BigDecimal 计算注意事项

    BigDecimal 在进行除法运算(divide)时一定要注意:如果被除数为变量,一定要指定精度 和 舍入模式,否则会报:Non-terminating decimal expansion; no ...

  3. JS 的三种定义变量 var let const

    Let 只在 let 命令所在的代码块内有效,在外就会报错 Let 是块级作用域,函数内部使用let定义后,对函数外部无影响 Let/const 不存在变量提升,使用前一定要声明后,在使用,否则会报错 ...

  4. 【力扣】454. 四数相加 II

    给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为了使问题简单化,所有的 A ...

  5. [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器

    [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 目录 [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 0x0 ...

  6. CF938A Word Correction 题解

    Content 有一个长度为 \(n\) 的,只包含小写字母的字符串,只要有两个元音字母相邻,就得删除后一个元音字母(\(\texttt{a,e,i,o,u,y}\) 中的一个),请求出最后得到的字符 ...

  7. CF106A Card Game 题解

    Content 一种纸牌游戏有许多张卡牌,每张卡牌有一个套装(S,H,D和 C)和一个等级(按升序排列6,7,8,9,T, J,Q,K,A). 规定以下情况卡牌 A 才能赢卡牌 B: A 有王牌套装, ...

  8. JavaScript数组的push()等方法的使用

    数组是值得有序集合.每个值在数组中有一个位置,用数字表示,叫做索引.JavaScript数组是无类型的:数组元素可以是任何类型,而且同一个数组中可以存在不同类型元素,甚至可以是对象或是其他数组,这就可 ...

  9. java数据类型:集合存储元素类型限制<泛型> ;自定义类指定泛型<T> 以及限制用法;派生子类泛型<T> super(泛型内参数); 泛型通配符?以及?限制用法

    问题背景 Java 集合有个缺点,把一个对象"丢进"集合里之后,集合就会"忘记"这个对象的数据类型,当再次取出该对象时 该对象的编译类型就变Object类型(其 ...

  10. JAVA实现根据图片生成缩略图、裁剪、压缩图片

    依赖(用来复制文件,可以根据自己的来) <dependency> <groupId>commons-io</groupId> <artifactId>c ...