当前项目中有这样一个需求:由前端用户的一个操作,需要触发到不同设备的消息推送。由于推送这个具体功能,我们采用了第三方的服务。而这个服务调用有时候可能会有延时,为此,我们希望将消息推送与用户前端操作实现异步执行,就是希望在后台自动执行,不阻塞前端用户的操作,而且最好能实现失败重试等功能。

经过一些研究比较,我们发现使用Hangfire这个组件可以较好地实现这个需求。为了给大家做一个演示,我这里简化了代码,做一个范例程序。

我在这里不准备详细介绍Hangfire的基本用法,有兴趣的同学们可以参考官方网站 http://hangfire.io/  和文档 http://docs.hangfire.io/en/latest/

第一步:创建ASP.NET Web API项目

第二步:安装必要的nuget package

打开Nuget Package Manager Console

首先安装Hangfire组件(Core,MemoryStorage),注意,因为后者是依赖前者的,所以我们只需要运行下面的命令即可

Install-Package Hangfire.MemoryStorage

Storage就是存储的意思,Hangfire的后台任务是需要一个地方保存起来,它默认支持SQL Server Storage和MemoryStorage。采用MemoryStorage无疑是最简单的(不需要有任何外部的依赖)。当然,最大的问题就是,因为是放在内存中的,万一网站出现问题重启,那么没有执行完的任务是会消失的。

如果要使用SQL Server的话,可以参考 http://docs.hangfire.io/en/latest/configuration/using-sql-server.html ,甚至还可以结合MSMQ来提高可用性 http://docs.hangfire.io/en/latest/configuration/using-sql-server-with-msmq.html

接下来为当前项目启用Owin的支持。关于什么是OWin,我这里也不准备多做说明,有兴趣的同学可以参考 : http://www.cnblogs.com/dudu/p/what-is-owin.html  和 http://owin.org/ 还有 http://www.asp.net/aspnet/overview/owin-and-katana/an-overview-of-project-katana

Install-Package Microsoft.Owin.Host.SystemWeb

第三步:添加Owin Startup Class

修改Startup.cs为下面这样的代码

  1. using Hangfire;
  2. using Hangfire.MemoryStorage;
  3. using Microsoft.Owin;
  4. using Owin;
  5.  
  6. [assembly: OwinStartup(typeof(WebApplicationWebApiHangfireSample.Startup))]
  7.  
  8. namespace WebApplicationWebApiHangfireSample
  9. {
  10. /// <summary>
  11. /// 演示Hangfire的配置
  12. /// 作者:陈希章
  13. /// </summary>
  14. public class Startup
  15. {
  16. public void Configuration(IAppBuilder app)
  17. {
  18. // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
  19.  
  20. //指定Hangfire使用内存存储后台任务信息
  21. GlobalConfiguration.Configuration.UseMemoryStorage();
  22. //启用HangfireServer这个中间件(它会自动释放)
  23. app.UseHangfireServer();
  24. //启用Hangfire的仪表盘(可以看到任务的状态,进度等信息)
  25. app.UseHangfireDashboard();
  26.  
  27. }
  28. }
  29. }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

第四步:实现一个简单的Web API,启动后台任务

  1. using Hangfire;
  2. using System;
  3. using System.Diagnostics;
  4. using System.Web.Http;
  5.  
  6. namespace WebApplicationWebApiHangfireSample.Controllers
  7. {
  8. /// <summary>
  9. /// 用来公开给前端用户调用的API
  10. /// 作者:陈希章
  11. /// </summary>
  12. public class MessageController : ApiController
  13. {
  14. /// <summary>
  15. /// 这个是用来发送消息的静态方法
  16. /// </summary>
  17. /// <param name="message"></param>
  18. public static void Send(string message)
  19. {
  20. EventLog.WriteEntry("EventSystem", string.Format("这是由Hangfire后台任务发送的消息:{0},时间为:{1}", message, DateTime.Now));
  21. }
  22.  
  23. public IHttpActionResult Post(string content)
  24. {
  25. //这里可以做一些业务判断或操作
  26.  
  27. //然后需要推送的时候,调用下面的方法即可
  28. BackgroundJob.Enqueue(() => Send(content));
  29.  
  30. //最后返回(这里是立即返回,不会阻塞)
  31. return Ok();
  32. }
  33. }
  34. }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

第五步:进行测试

我使用Fiddler来模拟客户端调用

我们可以很容易地发起大量的请求,例如下面这样

很快就在Dashboard中看到任务状态(有1000个任务)

但是很快(不到1秒钟的时间),这些任务就全部处理完了

我们可以在Windows事件日志中看到消息

以上就是我的简单演示例子。当然,如果还想要实现失败重试,或者更加有意思的一些功能(例如定时发送),可以继续参考官方文档。

这个范例代码可以通过这里下载  http://files.cnblogs.com/files/chenxizhang/WebApplicationWebApiHangfireSample.zip

在ASP.NET Web API项目中使用Hangfire实现后台任务处理的更多相关文章

  1. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(4)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  2. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(3)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  3. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(2)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  4. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(1)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  5. Web API项目中使用Area对业务进行分类管理

    在之前开发的很多Web API项目中,为了方便以及快速开发,往往把整个Web API的控制器放在基目录的Controllers目录中,但随着业务越来越复杂,这样Controllers目录中的文件就增加 ...

  6. ASP.NET Web API 2 中的属性路由使用(转载)

    转载地址:ASP.NET Web API 2 中的属性路由使用

  7. ASP.NET Web API 2中的错误处理

    前几天在webapi项目中遇到一个问题:Controller构造函数中抛出异常时全局过滤器捕获不到,于是网搜一把写下这篇博客作为总结. HttpResponseException 通常在WebAPI的 ...

  8. 在asp.net web form项目中添加webapi接口

    我有一个支付宝服务网关是ASP.NET WEB FORM项目,但是最近这个网关需要对外提供几个接口,想了下,使用web api比较合适,实现很简单,GO 1,首先添加一个文件夹名字叫App_Start ...

  9. 在ASP.NET Web API 2中使用Owin OAuth 刷新令牌(示例代码)

    在上篇文章介绍了Web Api中使用令牌进行授权的后端实现方法,基于WebApi2和OWIN OAuth实现了获取access token,使用token访问需授权的资源信息.本文将介绍在Web Ap ...

随机推荐

  1. 最简单的android自定义进度条样式

    一.自定义圆形进度条样式 1.在安卓项目drawable目录下新建一个xml文件如下:<?xml version="1.0" encoding="utf-8&quo ...

  2. CentOS 7 防止端口自动关闭

    tl;dr firewall-cmd --permanent --zone=public --add-port=2888/tcp firewall-cmd --reload #重新载入服务 永久配置f ...

  3. jQueryUI Draggable 和 Droppable 配合使用时遇到的两个坑

    jQueryUI 的 拖拽插件极大的方便了开发者对拖拽功能的实现,但是官方教程给的太笼统,在具体实现的时候很多地方不明确,这里说一下我遇到的两个 "小坑": 1:Draggable ...

  4. Spring的三种通过XML实现DataSource注入方式

    Spring的三种通过XML实现DataSource注入方式: 1.使用Spring自带的DriverManagerDataSource 2.使用DBCP连接池 3.使用Tomcat提供的JNDI

  5. git上传文件出错的时候

    $ git pull --rebase origin master 运行这个基本OK!

  6. SQL初步知识点

    varchar(n) 长度为 n 个字节的可变长度且非 Unicode 的字符数据.n 必须是一个介于 1 和 8,000 之间的数值.存储大小为输入数据的字节的实际长度,而不是 n 个字节. nva ...

  7. ex2-注释和井号

    代码: print("I could have code like this.") # and the commnt after is ignored.# You can also ...

  8. IIS Community Newsletter June 2013

    Announcements Windows 2012 Server R2 preview released Windows Server 2012 R2 provides a wide range o ...

  9. DDD实践问题之 - 关于论坛的帖子回复统计信息的更新的思考

    之前,在用ENode开发forum案例时,遇到了关于如何实现论坛帖子的回复的统计信息如何更新的问题.后来找到了自己认为比较合理的解决方案,分享给大家.也希望能和大家交流,擦出更多的火花. 论坛核心领域 ...

  10. 仿花田:相亲网站 意中人 已在GitHub上开源

    在园友的强烈呼唤下,我还是负责任的分享给大家,因为对代码比较熟悉一下,还是有些问题要说明,不然别人看起来会比较费劲.说实话除了这个bootstrap的界面风格和这件事情本身对大家有吸引力之外,内部的逻 ...