• .NET之Hangfire快速入门和使用


    什么是Hangfire

    Hangfire是一个开源且商业免费使用的工具函数库。可以让你非常容易地在ASP.NET应用(也可以不在ASP.NET应用)中执行多种类型的后台任务,而无需自行定制开发和管理基于Windows Service后台任务执行器。且任务信息可以被持久保存。内置提供集成化的控制台。

    Hangfire的基本特征与优点

    与quartz.net对比

    很大的原因在于项目需要一个后台可监控的应用,不用每次都要从服务器拉取日志查看,在没有ELK的时候相当不方便。Hangfire控制面板不仅提供监控,也可以手动的触发执行定时任务

     

    HangFire例子

    1、新建项目

    2、引用安装

     

    这里我们选择redis 作为持久化方式,所以引用

    Hangfire.Redis.StackExchange.StrongName

    配置面板、redis链接

    Startup.cs

     

     public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllersWithViews().AddControllersAsServices();
                GlobalStateHandlers.Handlers.Add(new SucceededStateExpireHandler(int.Parse(Configuration["Hangfire:JobExpirationTimeout"])));
                services.AddHostedService<RecurringJobsService>();
                services.AddHangfire(x =>
                {
                    var connectionString = Configuration["Hangfire:Redis:ConnectionString"];
                    x.UseRedisStorage(connectionString, new RedisStorageOptions()
                    {
                        //活动服务器超时时间
                        InvisibilityTimeout = TimeSpan.FromMinutes(60),
                        Db = int.Parse(Configuration["Hangfire:Redis:Db"])
                    });
                    x.UseDashboardMetric(DashboardMetrics.ServerCount)
                        .UseDashboardMetric(DashboardMetrics.RecurringJobCount)
                        .UseDashboardMetric(DashboardMetrics.RetriesCount)
                        .UseDashboardMetric(DashboardMetrics.AwaitingCount)
                        .UseDashboardMetric(DashboardMetrics.EnqueuedAndQueueCount)
                        .UseDashboardMetric(DashboardMetrics.ScheduledCount)
                        .UseDashboardMetric(DashboardMetrics.ProcessingCount)
                        .UseDashboardMetric(DashboardMetrics.SucceededCount)
                        .UseDashboardMetric(DashboardMetrics.FailedCount)
                           .UseDashboardMetric(DashboardMetrics.EnqueuedCountOrNull)
                              .UseDashboardMetric(DashboardMetrics.FailedCountOrNull)
                        .UseDashboardMetric(DashboardMetrics.DeletedCount);
                });
            }

    配置面板登录权限、作业通道

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Home/Error");
                }
                app.UseStaticFiles();
    
                app.UseRouting();
                app.UseAuthorization();
                var filter = new BasicAuthAuthorizationFilter(
            new BasicAuthAuthorizationFilterOptions
            {
                SslRedirect = false,
                RequireSsl = false,
                LoginCaseSensitive = false,
                Users = new[]
                {
                            new BasicAuthAuthorizationUser
                            {
                                Login = Configuration["Hangfire:Login"] ,
                                PasswordClear= Configuration["Hangfire:PasswordClear"]
                            }
                }
            });
                app.UseHangfireDashboard("", new DashboardOptions
                {
                    Authorization = new[]
                    {
                       filter
                    },
                });
                var jobOptions = new BackgroundJobServerOptions
                {
                    Queues = new[] { "critical", "test", "default" },
                    WorkerCount = Environment.ProcessorCount * int.Parse(Configuration["Hangfire:ProcessorCount"]),
                    ServerName = Configuration["Hangfire:ServerName"],
                    SchedulePollingInterval = TimeSpan.FromSeconds(1), //计划轮询间隔  支持任务到秒
                };
                app.UseHangfireServer(jobOptions);
            }
    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "Hangfire": {
        "Redis": {
          "ConnectionString": "localhost:6379,password=123456,abortConnect=false",
          "Db": 10
        },
        "Login": "admin", //账号
        "PasswordClear": "123456", //密码
        "ServerName": "hangfire001", //站点服务名称
        "JobExpirationTimeout": 1, //成功job过期时间 分钟
        "ProcessorCount": 5 //线程数
      },
      "AllowedHosts": "*"
    }

    使用作业

    using Hangfire;
    using Hangfire.Server;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Threading;
    using System.Threading.Tasks;
    using TestService;
    
    namespace hangfiretest.RecurringJobs
    {
        internal class RecurringJobsService : BackgroundService
        {
            private readonly IBackgroundJobClient _backgroundJobs;
            private readonly IRecurringJobManager _recurringJobs;
            private readonly ILogger<RecurringJobScheduler> _logger;
            public Itest _test { get; set; }
    
            public RecurringJobsService(
                [NotNull] IBackgroundJobClient backgroundJobs,
                [NotNull] IRecurringJobManager recurringJobs,
                [NotNull] ILogger<RecurringJobScheduler> logger)
            {
                _backgroundJobs = backgroundJobs ?? throw new ArgumentNullException(nameof(backgroundJobs));
                _recurringJobs = recurringJobs ?? throw new ArgumentNullException(nameof(recurringJobs));
                _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            }
    
            protected override Task ExecuteAsync(CancellationToken stoppingToken)
            {
                try
                {
                    _recurringJobs.AddOrUpdate<Itest>("seconds", i => _test.demo(), "*/1 * * * * *", queue: "critical");
                    //_backgroundJobs.Enqueue<Services>(x => x.LongRunning(JobCancellationToken.Null));
                    //_recurringJobs.AddOrUpdate("seconds", () => Console.WriteLine("Hello, seconds!"), "*/15 * * * * *");
                    //_recurringJobs.AddOrUpdate("minutely", () => Console.WriteLine("Hello, world!"), Cron.Minutely);
                    //_recurringJobs.AddOrUpdate("hourly", () => Console.WriteLine("Hello"), "25 15 * * *");
                    //_recurringJobs.AddOrUpdate("neverfires", () => Console.WriteLine("Can only be triggered"), "0 0 31 2 *");
                    //_recurringJobs.AddOrUpdate("Hawaiian", () => Console.WriteLine("Hawaiian"), "15 08 * * *", TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time"));
                    //_recurringJobs.AddOrUpdate("UTC", () => Console.WriteLine("UTC"), "15 18 * * *");
                    //_recurringJobs.AddOrUpdate("Russian", () => Console.WriteLine("Russian"), "15 21 * * *", TimeZoneInfo.Local);
                }
                catch (Exception e)
                {
                    _logger.LogError("An exception occurred while creating recurring jobs.", e);
                }
    
                return Task.CompletedTask;
            }
        }
    }

    已完成的job设置过期,防止数据无限增长

    using Hangfire.States;
    using Hangfire.Storage;
    using System;
    
    namespace hangfiretest
    {
        /// <summary>
        /// 已完成的job设置过期,防止数据无限增长
        /// </summary>
        public class SucceededStateExpireHandler : IStateHandler
        {
            public TimeSpan JobExpirationTimeout;
    
            public SucceededStateExpireHandler(int jobExpirationTimeout)
            {
                JobExpirationTimeout = TimeSpan.FromMinutes(jobExpirationTimeout);
            }
    
            public string StateName => SucceededState.StateName;
    
            public void Apply(ApplyStateContext context, IWriteOnlyTransaction transaction)
            {
                context.JobExpirationTimeout = JobExpirationTimeout;
            }
    
            public void Unapply(ApplyStateContext context, IWriteOnlyTransaction transaction)
            {
            }
        }
    }

    RUN起来

    是不是很简单啊,以前我是使用quartz,自从使用了hangfire,反正我是再也不想在使用quartz;有点类似git和svn的关系;

     

    完整代码:

    https://github.com/conanl5566/mydemo/tree/master/hangfire/hangfire.demo

     

     

     

  • 相关阅读:
    0725------Linux基础----------信号
    0723------Linux基础----------文件 IO 之 dup、dup2 和 fcntl 函数
    0722-----C++Primer听课笔记----------句柄类和智能指针
    0721-----C++Primer听课笔记----------继承
    0718-----C++Primer听课笔记----------运算符重载
    flex 弹性盒子模型一些案例.html
    布局—column(属性)
    css3中的动画处理
    CSS3中的变形处理(transform)属性
    jquery返回顶部特效
  • 原文地址:https://www.cnblogs.com/lyl6796910/p/13767128.html
Copyright © 2020-2023  润新知