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

星夢妙者
发布: 2025-09-28 09:15:14
原创
578人浏览过

在项目中引入后台任务时,通常我们会在windows环境下使用命令行程序结合计划任务或者直接生成windows服务来管理任务。然而,随着.net core的跨平台特性,linux环境下的计划任务虽然可用,但与传统方式类似,缺乏图形界面,执行结果只能通过查看服务器日志来确认。经过评估,我们决定采用hangfire来满足需求,因为它不仅提供图形化的用户界面,还简化了后台任务的注册过程。

Hangfire的安装和使用非常简单。首先,在项目中通过包管理器安装Hangfire:

PM> Install-Package Hangfire
登录后复制

对于Asp.Net Core项目,在Startup.cs文件的ConfigureServices方法中添加Hangfire的注册:

services.AddHangfire(x => x.UseSqlServerStorage("connection string"));
登录后复制

这里的connection string是数据库连接字符串,我选择使用的是Sql Server,但你也可以使用Redis、Mysql等其他数据库。

注册完成后,在Configure方法中添加以下代码:

app.UseHangfireServer();
app.UseHangfireDashboard();
登录后复制

项目启动后,Hangfire会进行相关数据结构的Migration。启动成功后,通过项目地址加上/Hangfire可以查看Hangfire是否正常运行,看到如下界面表示基本没有问题。

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

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

//执行后台脚本,仅执行一次
BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!"));

//延迟执行后台脚本,仅执行一次
BackgroundJob.Schedule(
    () => Console.WriteLine("Delayed!"),
    TimeSpan.FromDays(7));

//周期性任务
RecurringJob.AddOrUpdate(
    () => Console.WriteLine("Recurring!"),
    Cron.Daily);

//等上一任务完成后执行
BackgroundJob.ContinueWith(
    jobId,  //上一个任务的jobid
    () => Console.WriteLine("Continuation!"));
登录后复制

在.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后台会看到如下错误:

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

错误信息大致意思是不能使用接口或者抽象类,这是因为Hangfire无法找到实例。为了让Hangfire支持DI,我们需要创建一个MyActivator类,使其继承Hangfire.JobActivator类,代码如下:

Shell脚本编写基础 中文WORD版
Shell脚本编写基础 中文WORD版

Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。它虽然不是Linux系统核心的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Linux系统

Shell脚本编写基础 中文WORD版 24
查看详情 Shell脚本编写基础 中文WORD版
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中获取返回类型。

接下来,我们编写两个后台任务,CheckServiceTimerServiceCheckServiceCheck方法在执行计划时,会再次调用Hangfire来定时启动TimerService

CheckService:

public interface ICheckService
{
    void Check();
}
public class CheckService : ICheckService
{
    private readonly ILogger<CheckService> _logger;
    private ITimerService _timerService;
    public CheckService(ILoggerFactory loggerFactory,
        ITimerService timerService)
    {
        _logger = loggerFactory.CreateLogger<CheckService>();
        _timerService = timerService;
    }
    public void Check()
    {
        _logger.LogInformation($"check service start checking, now is {DateTime.Now}");
        BackgroundJob.Schedule(() => _timerService.Timer(), TimeSpan.FromMilliseconds(30));
        _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中注册这两个服务:

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.csConfigure方法中使用如下代码:

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

再次启动项目,我们的后台任务就会成功执行,截图如下:

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

参考资料:

以上就是在Asp.Net Core中使用DI的方式使用Hangfire构建后台执行脚本的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号