迷恋自留地 发表于 2021-7-4 22:13

.NET中Hangfire快速入门和使用

# .NET中Hangfire快速入门和使用
### 前言:
  定时任务调度问题,是一个老生常谈的问题。网上有许多定时任务调度的解决方案,对于我而言很早以前主要是使用Window计划和Window服务来做任务定时执行,然后就开始使用定时任务调度框架Quartz.Net。但是却一直没有上手过Hangfire这个自带后台任务调度面板,可以在后台手动执行任务的神奇的任务调度框架。前段时间终于开始对他下手了,通过在网上查阅了一些资料和查看了Hangfire在Github中的demo,终于在我自己的项目中用上了Hangfire。在该篇文章中主要简单介绍一下什么是Hangfire,Hangfire的基本特征与优点和分别使用MySQL,MS SQL Server作为存储使用。
  
### 一、Hangfire是什么:
  Hangfire是一个开源的.NET任务调度框架,提供了内置集成化的控制台,可以直观明了的查看作业调度情况,并且Hangfire不需要依赖于单独的应用程序执行(如:windows服务,window计划)。并且支持持久性存储。


### 二、Hangfire使用条件:
>Hangfire 不依赖于具体的.NET应用类型,包含.NET 和.NET Core。无需Windows服务/任务计划程序。

### 三、Hangfire的基本特征与优点:
>Hangfire的具有如下特性:
>1. 支持基于队列的任务处理:任务执行不是同步的,而是放到一个持久化队列中,以便马上把请求控制权返回给调用者。使用方法:BackgroundJob.Enqueue(() => Console.WriteLine("Simple!"));
>2. 延迟任务执行:不是马上调用方法,而是设定一个未来时间点再来执行。使用方法:BackgroundJob.Schedule(() => Console.WriteLine("Reliable!"), TimeSpan.FromDays(7));
>3. 循环任务执行:只需要简单的一行代码就可以添加重复执行的任务,其内置了常见的时间循环模式,也可以基于CRON表达式来设定复杂的模式。使用方法:RecurringJob.AddOrUpdate(() => Console.WriteLine("Transparent!"), Cron.Daily);


>Hangfire的具有如下有点:
>1. 持久化保存任务、队列、统计信息:默认使用SQL Server,也可以配合消息队列来降低队列处理延      迟,或配置使用Redis来获得更好的性能表现
>2. 内置自动重试机制:可以设定重试次数,还可以手动在控制台重启任务
除了调用静态方法外还支持实例方法能够捕获多语言状态:即可以把调用者的Thread.CurrentCulture和Thread.CurrentUICulture信息同任务持久保存在一起,以便任务执行的时候多语言信息是一致的
>3. 支持任务取消:使用CancellationToken这样的机制来处理任务取消逻辑
>4. 支持IoC容器:目前支持Ninject和Autofac比较常用的开源IoC容器
>5. 支持Web集群:可以在一台或多台机器上运行多个Hangfire实例以便实现冗余备份
>6. 支持多队列:同一个Hangfire实例可以支持多个队列,以便更好的控制任务的执行方式
>7. 并发级别的控制:默认是处理器数量的5倍工作行程,当然也可以自己设定
>8. 具备很好的扩展性:有很多扩展点来控制持久存储方式、IoC容器支持等

为什么要使用Hangfire这样的函数库呢?

1. 开发简单:无需自己额外做开发,就可以实现任务的队列执行、延迟执行和重复执行
2. 部署简单:可以同主ASP.NET应用部署在一起,测试和维护都相对简单
3. 迁移简单:由于宿主不仅限于ASP.NET,那么未来可以非常容易的把任务执行器放到其他地方(需要改变的就是在其他宿主中启动Hangfire服务器)
4. 扩展简单:由于开源且有很多扩展点,在现有插件都不满足自己需要的情况下能够容易的进行扩展
之前我把Hangfire运用到两种情况下:

后台长时间的科学计算:
1. 这样就可以让请求马上返回给客户端,后台完成长时间计算后,用SignalR实时提醒用户
2. 后台群发邮件:通过延迟和循环任务分批通过SendCloud这样的服务发送群发邮件
3. 当然,Hangfire的应用场景还很多,比如在后台处理电商卖家的订单。
![](https://img-blog.csdnimg.cn/20210704183049417.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzMyMzM2,size_16,color_FFFFFF,t_70)


### 四、Hangfire安装和使用:

#### 1. 控制台中的使用

NetGet安装`Hangfire `,`Hangfire.SqlServer`

>注意,在控制台应用程序或者window server中不推荐直接安装:Install-Package Hangfire ,因为它只是一个快速启动软件包,并包含您可能不需要的依赖项(例如,Microsoft.Owin.Host.SystemWeb等无关依赖项)

![](https://img-blog.csdnimg.cn/20210704204821166.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzMyMzM2,size_1,color_FFFFFF,t_70)MSMQ支持SQL Server作业存储实现,像其他Hangfire扩展一样,是一个NuGet包。您可以使用NuGet软件包管理器控制台窗口进行安装

Hangfire有这么几个表和索引来存储后台任务和相关的其他信息
![](https://img-blog.csdnimg.cn/20210704205141458.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzMyMzM2,size_1,color_FFFFFF,t_70)


```csharp
static void Main(string[] args)
      {
            GlobalConfiguration.Configuration
                .UseColouredConsoleLogProvider()
                .UseSqlServerStorage("Server=.;User ID=sa;Password=123456;database=Zhao;");

            //支持基于队列的任务处理:任务执行不是同步的,而是放到一个持久化队列中,以便马上把请求控制权返回给调用者。
            //   BackgroundJob.Enqueue(() => Console.WriteLine("Simple!"));
            //延迟任务执行:不是马上调用方法,而是设定一个未来时间点再来执行。
            //BackgroundJob.Schedule(() => Console.WriteLine("Reliable!"), TimeSpan.FromSeconds(5));
            //循环任务执行:一行代码添加重复执行的任务,其内置了常见的时间循环模式,也可基于CRON表达式来设定复杂的模式。
            RecurringJob.AddOrUpdate(() => Console.WriteLine("Transparent!"), Cron.Minutely);//注意最小单位是分钟
            
            using (var server = new BackgroundJobServer())
            {
                BackgroundJob.Enqueue(() => Console.WriteLine("Simple111"));

                Console.WriteLine("Hangfire Server started. Press any key to exit...");
                Console.ReadKey();
            }
            //RecurringJob.AddOrUpdate(() => Test(), Cron.Minutely);
      }

      //写入作业
       public static void Test()
      {
            //------
            Console.WriteLine("");
      }
```

#### 2. web中的使用
1. NuGet 命令行执行
>Install-Package Hangfire
2. 首先在ConfigureServices 方法中注册服务:

```csharp
public void ConfigureServices(IServiceCollection services)
      {
            services.AddHangfire(r=>r.UseSqlServerStorage("Data Source=.;Initial Catalog=HangfireDemo;User ID=sa;Password=123456"));
      }
```
3. 这里是配置数据库,数据库需要确保存在,这里配置的是SQL Server数据库,目前官方支持SQL Server。

然后在Configure 方法中加入HangfireServer及HangfireDashboard

```csharp
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
      {
            loggerFactory.AddConsole();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHangfireServer();
            app.UseHangfireDashboard();

            app.Run(context =>
            {
                return context.Response.WriteAsync("Hello from ASP.NET Core!");
            });
      }
```

访问地址:http://localhost:5000/hangfire
(也可以自定义路由,访问密码,具体参考官方文档)
![](https://img-blog.csdnimg.cn/20210704215002349.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzMyMzM2,size_1,color_FFFFFF,t_70)

4. 添加任务,访问
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704215551917.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzMyMzM2,size_16,color_FFFFFF,t_70)

```csharp
app.Map("/index", r =>
            {
                r.Run(context =>
                {
                  //任务每分钟执行一次
                  RecurringJob.AddOrUpdate(() => Console.WriteLine($"ASP.NET Core LineZero"), Cron.Minutely());
                  return context.Response.WriteAsync("ok");
                });
            });
```

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704215514767.png)

5.
Jobs 也就是查看所有的任务,我们可以在节目界面操作运行及删除,很方便。

还有更多的使用技巧,记得关注我`Net分享`
![](https://img-blog.csdnimg.cn/20210704215806940.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzMyMzM2,size_1,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20210704215902708.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzMyMzM2,size_1,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20210704220004965.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwNzMyMzM2,size_1,color_FFFFFF,t_70)



#### Hangfire相关使用学习资料:
官网地址:https://www.hangfire.io/

GitHub源码:https://github.com/HangfireIO/Hangfire

中文文档:https://www.bookstack.cn/read/Hangfire-zh-official/README.md

GitHub使用示例源码:https://github.com/HangfireIO/Hangfire.Samples(包括控制台应用程序,window服务,ASP.NET MVC,WebForm)

Hangfire使用文章汇总:https://www.bbsmax.com/R/xl56E0nrJr/

Hangfire使用参考:https://www.cnblogs.com/Leo_wl/p/5805287.html

Hangfire使用参考:https://www.cnblogs.com/owenzh/p/11623869.html

netpeng 发表于 2021-7-5 00:54

讲得很好很详细,想多听几堂课

abelwy 发表于 2021-7-5 08:54

一直在使用

tb612443 发表于 2021-7-5 09:12

目前还在使用Quartz

迷恋自留地 发表于 2021-7-5 20:38

tb612443 发表于 2021-7-5 09:12
目前还在使用Quartz

也挺好用,我也在用,可以做成服务,这个有可视化面板

tonylive 发表于 2021-7-6 09:03

这个和quartz比有什么优点?

tb612443 发表于 2021-7-6 09:16

迷恋自留地 发表于 2021-7-5 20:38
也挺好用,我也在用,可以做成服务,这个有可视化面板

netcore 现在很强大了,可惜晚了java十年

jjingtian 发表于 2021-7-6 10:25

插个眼,学习学习

sdbusqqq 发表于 2021-7-6 17:52

谢谢分享,学习一下。好像现在搞.NET的道友太少了
页: [1]
查看完整版本: .NET中Hangfire快速入门和使用