架构师_程序员

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 329|回复: 2

[ASP.NET] asp.net后台任务hangfire框架教程

[复制链接]
跳转到指定楼层
楼主
发表于 2019-5-24 09:51:10
zu
Hangfire适用于大多数.NET平台:.NET Framework 4.5或更高版本,.NET Core 1.0或更高版本,任何与.NET Standard 1.3兼容的平台。您可以将它与几乎任何应用程序框架集成,包括ASP.NET,ASP.NET Core,控制台应用程序,Windows服务,WCF,以及像Nancy或ServiceStack这样的社区驱动。

适用场景:后台异步发送电子邮件,并尽快向用户返回响应。定时执行任务、循环执行任务、异步执行耗时任务、A任务执行完成再执行B任务、批量执行任务。
我以前的做法方式:

c# 封装了一个万能QueueHelper队列
https://www.itsvse.com/thread-5029-1-1.html
(出处: 架构师_程序员)


您可以将后台处理放在ASP.NET应用程序中,而无需使用其他进程,如Windows服务。Hangfire的代码已准备好在部署过程中意外进程终止,应用程序池回收和重新启动。由于使用了持久存储,因此您不会丢失任何后台作业

首先,效果图如下:




上图是Hangfire Dashboard仪表盘,非常有用,可以查看后台任务状况,也很炫酷,所以,是必须配置的。

仪表板UI需要启动类,仅当您使用Startup类配置Hangfire时,Dashboard UI才可用

一开始,我没有配置Hangfire Dashboard仪表盘,会遇到以下错误:

The following errors occurred while attempting to load the app.
- No assembly found containing an OwinStartupAttribute.
- No assembly found containing a Startup or [AssemblyName].Startup class.
To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of "false" in your web.config.
To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config.



解决办法:

当使用基于Global.asax.cs文件的初始化时,您可能还需要禁用OWIN的启动类检测。

  1. <!-- web.config -->
  2. <appSettings>
  3.   <add key="owin:AutomaticAppStartup" value="false"/>
  4. </appSettings>
复制代码
我们开始进入正题,教程开始:

1:框架要满足hangfire的需求,我的项目是.net 4.6.2,所以,可以正常安装hangfire,.net 4.0的项目就不用试了,不支持!

2:nuget命令如下:

  1. Install-Package Hangfire.Core
  2. Install-Package Hangfire.SqlServer
  3. Install-Package Hangfire.AspNet
复制代码
3:OWIN Startup类旨在将Web应用程序引导逻辑保留在一个位置。在Visual Studio 2013中,您可以通过右键单击项目并选择Add / OWIN Startup Class菜单项来添加它。如下图:



在项目根目录新建一个Startup.cs文件。

4:配置数据库连接字符串,我这里使用的sql server 2012版本,在web.config配置如下:

  1.   <connectionStrings>
  2.     <add name="TestDb" connectionString="Data Source=127.0.0.1;Initial Catalog=itsvse;user id=sa;password=123456" providerName="System.Data.SqlClient" />
  3.   </connectionStrings>
复制代码
5:配置Hangfire Dashboard仪表盘访问过滤器,新建HangfireAuthorizationFilter.cs文件。

默认情况下,只允许对Hangfire Dashboard进行本地访问。必须配置仪表板授权才能允许远程访问。

  1. using Hangfire.Annotations;
  2. using Hangfire.Dashboard;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Web;

  7. namespace Itsvse.AdminWebUI.Filters
  8. {
  9.     public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter
  10.     {
  11.         public bool Authorize([NotNull] DashboardContext context)
  12.         {
  13.             //直接返回true 允许所有人可以访问
  14.             return true;
  15.         }
  16.     }
  17. }
复制代码

6:配置Startup.cs类,代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using Itsvse.AdminWebUI.Filters;
  5. using Hangfire;
  6. using Microsoft.Owin;
  7. using Owin;

  8. [assembly: OwinStartup(typeof(Itsvse.AdminWebUI.Startup))]

  9. namespace Itsvse.AdminWebUI
  10. {
  11.     public class Startup
  12.     {
  13.         public void Configuration(IAppBuilder app)
  14.         {
  15.             // 有关如何配置应用程序的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkID=316888
  16.             // Map Dashboard to the `http://<your-app>/hangfire` URL.
  17.             app.UseHangfireAspNet(GetHangfireServers);
  18.             app.UseHangfireDashboard("/hangfire", new DashboardOptions
  19.             {
  20.                 Authorization = new[] { new HangfireAuthorizationFilter() },//默认情况下,只允许对Hangfire Dashboard进行本地访问。必须配置仪表板授权才能允许远程访问。
  21.                 IsReadOnlyFunc = (Hangfire.Dashboard.DashboardContext context) => true //只读模式
  22.             });
  23.             BackgroundJob.Enqueue(() => System.Diagnostics.Debug.WriteLine("Hello world from Hangfire!"));
  24.             for (int i = 0; i < 100; i++)
  25.             {
  26.                 var jobId = BackgroundJob.Schedule(
  27.                 () => System.Diagnostics.Debug.WriteLine("Delayed!itsvse.com"),
  28.                 TimeSpan.FromSeconds(i));
  29.             }
  30.         }

  31.         private IEnumerable<IDisposable> GetHangfireServers()
  32.         {
  33.             //sql server持久化连接字符串
  34.             string sqlCon = System.Configuration.ConfigurationManager.ConnectionStrings["TestDb"].ConnectionString;
  35.             Hangfire.GlobalConfiguration.Configuration
  36.                 .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
  37.                 .UseSimpleAssemblyNameTypeSerializer()
  38.                 .UseRecommendedSerializerSettings()
  39.                 .UseSqlServerStorage(sqlCon, new Hangfire.SqlServer.SqlServerStorageOptions
  40.                 {
  41.                     CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
  42.                     SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
  43.                     QueuePollInterval = TimeSpan.Zero,
  44.                     UseRecommendedIsolationLevel = true,
  45.                     UsePageLocksOnDequeue = true,
  46.                     DisableGlobalLocks = true
  47.                 });

  48.             yield return new BackgroundJobServer();
  49.         }
  50.     }


  51. }


复制代码

7:启动网站项目

按下调试模式运行应用程序F5(这需要查看Debug.WriteLine方法的输出)。然后在“ 输出”窗口中检查以下消息,以查看后台处理是否已成功启动。



同时,数据库也多了11张表,保证所有的任务都能正常执行,在iis回收或者进程重启下,任务也不会丢失,如下图:



http://<your-web-app>/hangfire

访问Dashboard UI网址,就可以看到文章最上面的效果图了。

附上用法

Fire-And-forget(发布/订阅)

这是一个主要的后台任务类型,持久化消息队列会去处理这个任务。当你创建了一个发布/订阅任务,该任务会被保存到默认队列里面(默认队列是"Default",但是支持使用多队列)。多个专注的工作者(Worker)会监听这个队列,并且从中获取任务并且完成任务。

  1. var jobId = BackgroundJob.Enqueue(
  2.     () => Console.WriteLine("Fire-and-forget!"));
复制代码

延迟

如果想要延迟某些任务的执行,可以是用以下任务。在给定延迟时间后,任务会被排入队列,并且和发布/订阅任务一样执行。
  1. var jobId = BackgroundJob.Schedule(
  2.     () => Console.WriteLine("Delayed!"),
  3.     TimeSpan.FromDays(7));
复制代码

循环

按照周期性(小时,天等)来调用方法,请使用RecurringJob类。在复杂的场景,您可以使用CRON表达式指定计划时间来处理任务。

  1. RecurringJob.AddOrUpdate(
  2.     () => Console.WriteLine("Recurring!"),
  3.     Cron.Daily);
复制代码

连续

连续性允许您通过将多个后台任务链接在一起来定义复杂的工作流。

  1. var id = BackgroundJob.Enqueue(() => Console.WriteLine("Hello, "));
  2. BackgroundJob.ContinueWith(id, () => Console.WriteLine("world!"));
复制代码

官方文档链接:https://docs.hangfire.io/en/latest/

(完)






上一篇:视频数据算法分享笔记
下一篇:请求被中止: 未能创建 SSL/TLS 安全通道解决方案
帖子永久地址: 

架构师_程序员 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与架构师_程序员享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和架构师_程序员的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、架构师_程序员管理员和版主有权不事先通知发贴者而删除本文

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
沙发
发表于 2019-5-24 10:12:25
本帖最后由 YuAn 于 2019-5-24 10:20 编辑

不错的文章 学习了
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
板凳
发表于 2019-5-24 10:12:46
支持 支持
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。

Mail To:help@itsvse.com

QQ|Archiver|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2019-7-21 09:02

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表