之前使用Quartz.Net,后来发现hangfire对Core的继承更加的好,而且自带管理后台,这就比前者好用太多了。

安装注册

安装

PM> Install-Package Hangfire

Startup.cs,在ConfigureServices方法中添加注册:

services.AddHangfire(x => x.UseSqlServerStorage("connection string"));

SqlServer是使用这种方式,其他方式见官方的文档及相应插件。

注册完成后,还需要在Configure方法中,添加如下高亮部分的代码:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{ if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
} //添加Hangfire
app.UseHangfireServer();
app.UseHangfireDashboard();
配置完毕后运行我们的项目,这时Hangfire会自动在数据库中创建结构,数据库中会新建如下表:

现在在网站根目录+/Hangfire即可查看管理后台界面如下:

基本使用

Hangfire的使用非常简单,基本上使用以下几个静态方法:

//执行后台脚本,仅执行一次
BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!")); //延迟执行后台脚本呢,仅执行一次
BackgroundJob.Schedule(
() => Console.WriteLine("Delayed!"),
TimeSpan.FromDays()); //周期性任务
RecurringJob.AddOrUpdate(
() => Console.WriteLine("Recurring!"),
Cron.Daily); //等上一任务完成后执行
BackgroundJob.ContinueWith(
jobId, //上一个任务的jobid
() => Console.WriteLine("Continuation!"));

注意,周期性使用可以使用Cron表达式

# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
# │ │ │ │ │ 7 is also Sunday on some systems)
# │ │ │ │ │
# │ │ │ │ │
# * * * * * command to execute
Entry Description Equivalent to
@yearly (or @annually) 每年1月3号2:01分运行 1 2 3 1 *
@monthly 每月3号2:01分运行 1 2 3 * *
@weekly 每周日的2:01分运行 1 2 * * 0
@daily 每天的2:01分运行 1 2 * * *
@hourly 每小时的1分运行 1 * * * *
@reboot Run at startup N/A

依赖注入

在.Net Core中处处是DI,一不小心,你会发现你在使用Hangfire的时候会遇到各种问题,比如下列代码:

public class HomeController : Controller
{
private ILogger<HomeController> _logger;
public HomeController(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<HomeController>();
}
public IActionResult Index()
{
_logger.LogInformation("start index");
BackgroundJob.Enqueue(() => _logger.LogInformation("this a job!"));
return View();
} }

项目启动后,你能正常访问,但在Hangfire后台你会看到如下错误:


错误信息呢大概意思是不能使用接口或者抽象方法类,其实就是因为Hangfire没有找到实例,那如何让Hangfire支持DI呢?

我们先创建一个MyActivator类,使其继承Hangfire.JobActivator类,代码如下:

public class MyActivator : Hangfire.JobActivator
{
private readonly IServiceProvider _serviceProvider;
public MyActivator(IServiceProvider serviceProvider) => _serviceProvider = serviceProvider; public override object ActivateJob(Type jobType)
{
return _serviceProvider.GetService(jobType);
}
}

重写了ActivateJob方法,使其返回的类型从我们的IServiceProvider中获取。

我们试着写两个后台脚本,CheckService和TimerService,CheckService的Check方法在执行计划时,会再次调用Hangfire来定时启动TimerService:

CheckService:

public interface ICheckService
{
void Check();
}
public class CheckService : ICheckService
{
private readonly ILogger<CheckService> _logger;
private ITimerService _timeservice;
public CheckService(ILoggerFactory loggerFactory,
ITimerService timerService)
{
_logger = loggerFactory.CreateLogger<CheckService>();
_timeservice = timerService;
} public void Check()
{
_logger.LogInformation($"check service start checking, now is {DateTime.Now}");
BackgroundJob.Schedule(() => _timeservice.Timer(), TimeSpan.FromMilliseconds());
_logger.LogInformation($"check is end, now is {DateTime.Now}");
}
}

TimerService:

public interface ITimerService
{
void Timer();
}
public class TimerService : ITimerService
{
private readonly ILogger<TimerService> _logger;
public TimerService(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<TimerService>();
}
public void Timer()
{
_logger.LogInformation($"timer service is starting, now is {DateTime.Now}");
_logger.LogWarning("timering");
_logger.LogInformation($"timer is end, now is {DateTime.Now}");
}
}

目前还无法使用,我们必须在Startup中注册这2个service:

services.AddScoped<ITimerService, TimerService>();
services.AddScoped<ICheckService, CheckService>();

我们在HomeController修改以下:

public IActionResult Index()
{
_logger.LogInformation("start index");
BackgroundJob.Enqueue<ICheckService>(c => c.Check());
return View();
}

好,一切就绪,只差覆盖原始的Activator了,我们可以在Startup.cs中的Configure方法中使用如下代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
{
GlobalConfiguration.Configuration.UseActivator<MyActivator>(new MyActivator(serviceProvider));
……
……
}

默认情况下Configure方法时没有IServiceProvider参数的,请手动添加

再次启动,我们的Job就会成功执行,截图如下:

补充:以上在开发环境可以正常使用,一旦发布到正式环境会报401 Unauthorized未授权错误,原因是 Hangfire 默认增加了授权配置。

解决方式:

增加CustomAuthorizeFilter

public class CustomAuthorizeFilter : IDashboardAuthorizationFilter
{
public bool Authorize([NotNull] DashboardContext context)
{
//var httpcontext = context.GetHttpContext();
//return httpcontext.User.Identity.IsAuthenticated;
return true;
}
}

Configure增加配置:

app.UseHangfireDashboard("/hangfire", new DashboardOptions() {
Authorization = new[] { new CustomAuthorizeFilter() }
});

参考资料

    

Core中使用Hangfire的更多相关文章

  1. ASP.NET Core 中使用 Hangfire 定时启动 Scrapyd 爬虫

    用 Scrapy 做好的爬虫使用 Scrapyd 来管理发布启动等工作,每次手动执行也很繁琐;考虑可以使用 Hangfire 集成在 web 工程里. Scrapyd 中启动爬虫的请求如下: curl ...

  2. Hangfire在ASP.NET CORE中的简单实现

    hangfire是执行后台任务的利器,具体请看官网介绍:https://www.hangfire.io/ 新建一个asp.net core mvc 项目 引入nuget包 Hangfire.AspNe ...

  3. 在Asp.Net Core中使用DI的方式使用Hangfire构建后台执行脚本

    最近项目中需要用到后台Job,原有在Windows中我们会使用命令行程序结合计划任务或者直接生成Windows Service,现在.Net Core跨平台了,虽然Linux下也有计划任务,但跟原有方 ...

  4. Hangfire在ASP.NET CORE中的简单实现方法

    hangfire是执行后台任务的利器,具体请看官网介绍:https://www.hangfire.io/ 新建一个asp.net core mvc 项目 引入nuget包 Hangfire.AspNe ...

  5. MVC中使用Hangfire执行定时任务

    需求描述 项目中有一个通知公告的功能,在后台管理员添加公告后需要推送消息给所有注册用户,让其查看消息.消息推送移动端采用极光推送,但是消息在何时发送是个问题,比如说有一个重要的会议通知,可能希望在会议 ...

  6. 如何在 ASP.Net Core 中实现 健康检查

    健康检查 常用于判断一个应用程序能否对 request 请求进行响应,ASP.Net Core 2.2 中引入了 健康检查 中间件用于报告应用程序的健康状态. ASP.Net Core 中的 健康检查 ...

  7. .NET Core中的认证管理解析

    .NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...

  8. ASP.NET Core 中的那些认证中间件及一些重要知识点

    前言 在读这篇文章之间,建议先看一下我的 ASP.NET Core 之 Identity 入门系列(一,二,三)奠定一下基础. 有关于 Authentication 的知识太广,所以本篇介绍几个在 A ...

  9. Asp.net Core中使用Session

    前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...

随机推荐

  1. ORACLE EBS xml publisher 报表输出字符字段前部"0"被EXCEL自动去掉问题

    http://www.cnblogs.com/lzsu1989/archive/2012/10/17/2728528.html   Oracle  EBS 提供多种报表的开发和输出形式,由于MS Ex ...

  2. Windows下VM安装MacOS

    我们在使用Windows操作系统的情况下,不去买苹果电脑,想去玩玩Mac苹果操作系统,有两种选择,一种就是安装黑苹果(就是在非苹果电脑上安装MacOS)这种方式不推荐,因为你会遇到很多很多不兼容问题, ...

  3. Redis键迁移

    Redis键迁移   在使用Redis的过程中,很多时候我们会遇到需要进行键迁移的问题,需要将指定Redis中的指定数据迁移到其他Redis当中,键迁移有三种方法,我们来进行一一介绍. 一.move ...

  4. EnyimMemcached中用DateTime参数设置过期后赋值有问题的解决.

    环境: win10 64位.memcached 1.4.4 64位.EnyimMemcached 2.16.0(ps:2.13.0也有此问题,别的版本就没试了). EnyimMemcached git ...

  5. EF 多对多循环引用序列化失败 解决办法

    错误:Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.tbldph_901D48A194FB31 ...

  6. 理解DDoS防护本质:基于资源较量和规则过滤的智能化系统

    本文由  网易云发布. 随着互联网生态逐渐形成,DDoS防护已经成为互联网企业的刚需要求,网易云安全(易盾)工程师根据DDoS的方方面面,全面总结DDoS的攻防对抗. 1.什么是DDoS DDoS全称 ...

  7. [Uliweb]-URL映射

    URL映射¶ Uliweb使用Werkzeug的Routing来进行URL的处理.当你使用manage.py的makeapp命令生成一个新 的App时,它会自动生成views.py文件,其中会自动从u ...

  8. A Tool to Clip Images

    using Microsoft.Win32; using System; using System.IO; using System.Text.RegularExpressions; using Sy ...

  9. 769. Max Chunks To Make Sorted

    Given an array arr that is a permutation of [0, 1, ..., arr.length - 1], we split the array into som ...

  10. oh-my-zsh 安装及使用

    什么是 oh-my-zsh oh-my-zsh 是基于 zsh 的功能做了一个扩展,方便的插件管理.主题自定义,以及漂亮的自动完成效果. oh-my-zsh 安装及插件安装 查看系统中 zsh 及版本 ...