• .net core 之Hangfire任务调度


    Hangfire可用作任务调度,类似延迟任务、队列任务、批量任务和定时任务等。

    一、nuget Hangfire包

    找到Hangfire.AspNetCore和Hangfire.SqlServer包,可以在nuget面板中找到或直接像如下方式安装:

    Install Package Hangfire.AspNetCore

    Install Package Hangfire.SqlServer

    二、在Startup.cs文件中加入以下代码:

    写一个Hangfire的扩展类,如下所示:

       public static class HangFireModule
        {
            public static IApplicationBuilder UseHangfire(this IApplicationBuilder app)
            {
                app.UseHangfireServer();
                app.UseHangfireDashboard();
    
                return app;
            }
    
            public static IServiceCollection AddHangfire(this IServiceCollection services)
            {
                services.AddHangfire(x => x.UseSqlServerStorage(ConfigurationSetting.Configuration["ConnectionString:MyDb_Hangfire"]));
                return services;
            }
        }

    在Startup的ConfigureServices方法中,加入services.AddHangfire();

    在Startup的Configure方法中,加入app.UseHangfire();

    三、自动加入任务

    1.在当前模块中,新创建一个名为IHangfireTask的接口,将其注册为瞬时生命周期服务。我们将要实现的是,从此以后,继承该接口的类型都会被自动加入到任务调度中。

        /// <summary>
        ///  Hangfire任务接口,任何继承该接口的都会加入到Hangfire任务
        /// </summary>
        public interface IHangfireTask : ITransient {
            /// <summary>
            /// 运行hangfire任务
            /// </summary>
            void Run();
        }

    ITransient接口的作用就是,将所有继承ITransient的接口和类型注册为瞬时生命周期的服务。

    2.在HangFireModule中新增一个UseHangfireTask扩展方法,目的是在Startup的Configure方法中使用,在程序启动的时候就执行该方法。

            //运行Hangfire任务
            public static void UseHangfireTask(this IApplicationBuilder app) {
                //找到继承了IHangfireTask接口的实例
                IList<IHangfireTask> list = ServiceLocator.Services.GetServices<IHangfireTask>()?.ToList();
                if (list?.Count > 0) {
                    foreach (var item in list) {
                        item.Run();
                    }
                }
            }

    加入到Startup的Configure方法中:

     public void Configure(IApplicationBuilder app, IHostingEnvironment env,IServiceProvider serviceProvider)
            {
                ServiceLocator.SetServices(serviceProvider);
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();             
                }
                else
                {
                    app.UseExceptionHandler();
                }
            
                 app.UseMvc();        
    
                app.UseSwagger();
                app.UseSwaggerUi();
    
                app.UseHangfire(); 
                app.UseHangfireTask();            
                
            }

    如此这样,我们就做到了在程序刚启动时,程序就会自动去找到继承自IHangfireTask接口的所有类型并运行它们的Run()方法。

    我们可以在Run()方法中实现诸如Hangfire的BackgroundJob或RecurringJob等任务。

    接下来我们就用代码来实现一下!

    我们现在想实现一个定时任务,则看如下代码:

       public class RecurringTask:IHangfireTask
       {
           private log4net.ILog log => LogHelper.Log4NetInstance.LogFactory(typeof(RecurringTask));
    
           public void RunTask()
           {
                log.Info("每分钟执行一次定时任务");
           }
         
            public void Run()
            {
                RecurringJob.AddOrUpdate(()=> RunTask(), "* * * * *");
            }
        }

    这里有一个地方需要注意,在使用RecurringJob或BackgroundJob的时候,就例如()=> RunTask()这个,RunTask方法的访问修饰符必须是public如果有必要,尽量在RunTask方法内被调用的其他方法的访问修饰符也定义为public。

    在Hangfire中,Cron表达式包含五个字段:分钟、小时、日期、月份、周,因此定时任务最低也只能是一分钟,没有秒数可供选择。

    接下来我们看看程序运行的结果:

    四、Hangfire的基本任务

    1. BackgroundJob.Enqueue

    作用:将一个任务放入到某个持久化的队列中并挨个执行,以便程序可以继续执行其他代码。该任务只执行一次。

    实现:BackgroundJob.Enqueue(() => RunTask());

    2. BackgroundJob.Schedule

    作用:将一个任务延迟到某个时间点后执行。

    实现:BackgroundJob.Schedule(() => RunTask(), TimeSpan.FromSeconds(30));

    即在30秒后才执行RunTask()方法。

    3. RecurringJob.AddOrUpdate

    作用:重复执行一个任务,一般用作定时任务处理。

    实现:RecurringJob.AddOrUpdate(()=> RunTask(), "* * * * *");

    即每分钟都执行一次RunTask()方法。

    4. BackgroundJob.ContinueWith

    作用:类似工作流的形式,将多个任务连接起来按照顺序执行。

    实现:

    string jobId = BackgroundJob.Schedule(() => Console.WriteLine("第一个任务"),TimeSpan.FromSeconds(10));
    BackgroundJob.ContinueWith(jobId, () => RunTask());

    注意:以上RunTask()方法的访问修饰符必须是public

  • 相关阅读:
    基于物品属性的过滤
    第一个极小的机器学习的应用
    基于物品过滤的Slope One 算法
    【转】Python爬虫(1)_基本原理
    程序猿面试题集锦
    Django:popup弹出框简单应用实例
    【转】Python max内置函数详细介绍
    MySQL数据库(9)_MySQL数据库常用操作命令
    【转】Python的hasattr() getattr() setattr() 函数使用方法详解
    Git常用命令
  • 原文地址:https://www.cnblogs.com/williamwsj/p/9042510.html
Copyright © 2020-2023  润新知