考虑下如下代码,在数据保存后,需要发送邮件,发送邮件是个耗时的工作。

我们的目的是,数据保存成功后,就可以返回响应了,发送邮件不重要,不需要等待邮件发送成功

[HttpPost]
public ActionResult Create(Comment model)
{
if (ModelState.IsValid)
{
_db.Comments.Add(model);
_db.SaveChanges();
 MailMessage message = new MailMessage();
message.To.Add("xx@126.com");
message.Subject = "主题是";
message.Body = string.Concat(HtmlEmailHeader, Body, HtmlEmailFooter);
message.BodyEncoding = System.Text.Encoding.UTF8;
message.From = new MailAddress(From);
message.SubjectEncoding = System.Text.Encoding.UTF8;
message.IsBodyHtml = true; SmtpClient client = new SmtpClient("relay.mail.server");
        client.Send(Message);//耗时操作 
}
return RedirectToAction("Index");
}

改成异步是否能达到这个效果呢?

答案是否定的!!虽然加入了异步方法,但是只有action里所有的代码执行完毕后才能返回响应!

await(await表达式表示等待异步方法执行完,并取返回值,因此遇到await关键字,会阻塞线程) 后面的异步方法还是要执行完毕后,才会继续执行下面的代码,跟同步方法一样,并不会节省时间。

所以异步可以提高效率/吞吐量,但是不能节省时间。

[HttpPost]
public async Task<ActionResult> Create(Comment model)
{
if (ModelState.IsValid)
{
_db.Comments.Add(model);
_db.SaveChanges();

//异步范例1

HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
Console.WriteLine("上面的异步方法是否执行完跟我没关系,我还是执行到这里了");
string urlContents = await getStringTask;//必须等client.GetStringAsync执行完

Console.WriteLine(urlContents.Length.ToString());上面的语句执行完才轮到我。

//异步反例2
MailMessage message = new MailMessage();
message.To.Add("xx@126.com");
message.Subject = "主题是";
message.Body = string.Concat(HtmlEmailHeader, Body, HtmlEmailFooter);
message.BodyEncoding = System.Text.Encoding.UTF8;
message.From = new MailAddress(From);
message.SubjectEncoding = System.Text.Encoding.UTF8;
message.IsBodyHtml = true; SmtpClient client = new SmtpClient("relay.mail.server"); await client.SendMailAsync(message); //await 这里会阻塞线程,直到邮件发送完毕
}
       return RedirectToAction("Index");//发送完邮件才执行到这里!
}

可以用后台线程吗?

答案也是否定的!

IIS工作线程是用于处理请求的,不适合运行后台任务,当应用程序池回收的时候,会丢掉。

最后,介绍 Hangfire

http://docs.hangfire.io/en/latest/tutorials/send-email.html#id3

mvc项目,添加nuget包 hanfire

安装包完毕后,可以看到,默认使用了sqlserver作为存储,并依赖Owin

mvc根目录创建startup.cs,并配置sqlserver连接字符串

using Hangfire;
using Microsoft.Owin;
using Owin;
using System; [assembly: OwinStartupAttribute(typeof(HangFire.Startup))]
namespace HangFire
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
string connectionStr = "Database=yourdb;Server=.;Uid=xxx;Pwd=xxx;Enlist=False;Pooling=true;Connection Reset=false;Trusted_Connection=no;Connect TimeOut=3000;";
GlobalConfiguration.Configuration
.UseSqlServerStorage(connectionStr); BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!"));//测试 app.UseHangfireDashboard();
app.UseHangfireServer();
}
}
}

运行mvc项目,因为在startup.cs里,加了BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget!"));//测试

所以Hangfire第一次执行的时候,会在sqlserver里创建相关的表

下面把发邮件的action改造下

[HttpPost]
public ActionResult Create(Comment model)
{
if (ModelState.IsValid)
{
_db.Comments.Add(model);
_db.SaveChanges();
MailMessage message = new MailMessage();
message.To.Add("xx@126.com");
message.Subject = "主题是";
message.Body = string.Concat(HtmlEmailHeader, Body, HtmlEmailFooter);
message.BodyEncoding = System.Text.Encoding.UTF8;
message.From = new MailAddress(From);
message.SubjectEncoding = System.Text.Encoding.UTF8;
message.IsBodyHtml = true; SmtpClient client = new SmtpClient("relay.mail.server");
BackgroundJob.Enqueue(() => client.Send(message));//发送工作交给Hangfire去后台处理了
}
return RedirectToAction("Index");//不管邮件是否发送成功就返回响应了
}

  

mvc中使用Hangfire处理后台任务的更多相关文章

  1. MVC中使用Hangfire执行定时任务

    需求描述 项目中有一个通知公告的功能,在后台管理员添加公告后需要推送消息给所有注册用户,让其查看消息.消息推送移动端采用极光推送,但是消息在何时发送是个问题,比如说有一个重要的会议通知,可能希望在会议 ...

  2. AspNet MVC中使用Hangfire执行定时任务

    Hangfire在Aspnet中执行定时任务: 第一步: NuGet中加入Hangfire包 第二步: 添加Owin的自启动 第三步.Hangfire的后台控制仪表盘默认情况下只能本地访问,外网访问需 ...

  3. MVC中使用Hangfire按秒执行任务

    更新Hangfire版本到1.7.0,才支持使用按秒循环任务执行 RecurringJob.AddOrUpdate("test",()=>writeLog("每20 ...

  4. 在ASP.NET Web API项目中使用Hangfire实现后台任务处理

    当前项目中有这样一个需求:由前端用户的一个操作,需要触发到不同设备的消息推送.由于推送这个具体功能,我们采用了第三方的服务.而这个服务调用有时候可能会有延时,为此,我们希望将消息推送与用户前端操作实现 ...

  5. .NetCore MVC中的路由(2)在路由中使用约束

    p { margin-bottom: 0.25cm; direction: ltr; color: #000000; line-height: 120%; orphans: 2; widows: 2 ...

  6. .NetCore MVC中的路由(1)路由配置基础

    .NetCore MVC中的路由(1)路由配置基础 0x00 路由在MVC中起到的作用 前段时间一直忙于别的事情,终于搞定了继续学习.NetCore.这次学习的主题是MVC中的路由.路由是所有MVC框 ...

  7. Asp.Net MVC中使用StreamReader读取“Post body”之应用场景。

    场景:有三个市场(Global.China.USA),对前台传过来的数据有些验证需要细化到每个市场去完成. 所以就出现了基类(Global)和派生类(China.USA) 定义基类(Global)Pe ...

  8. 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...

  9. ASP.NET Core MVC 中的 [Controller] 和 [NonController]

    前言 我们知道,在 MVC 应用程序中,有一部分约定的内容.其中关于 Controller 的约定是这样的. 每个 Controller 类的名字以 Controller 结尾,并且放置在 Contr ...

随机推荐

  1. canvas之旋转一条线段

    <canvas id="canvas" width="600" height="500" style="background ...

  2. Oracle段高水位(HWM, high water mark)问题

    Oracle对表做全表扫描的时候 ,会扫描完HWM以下的数据块.如果某个表delete(delete操作不会降低高水位)了大量数据,那么这时对表做全表扫描就会做很多无用功,扫描了一大堆数据块,最后发现 ...

  3. redis改密码

    一. 如何初始化redis的密码? 总共2个步骤: a.在配置文件中有个参数: requirepass  这个就是配置redis访问密码的参数. 比如 requirepass test123 b.配置 ...

  4. cookies,sessionStorage,localStorage的区别

    sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据.有了本地数据,就可以避免数据在浏览器和服务器间不必 ...

  5. ansible初识三

    一.setup模块 ansible的 setup模块主要用来收集信息, 查看参数: [root@localhost ~]# ansible-doc -s setup # 查看参数,部分参数如下: fi ...

  6. Memcache线上常见问题(缓存雪崩、缓存无底洞、永久数据被踢)

    缓存雪崩现象 一般是由于某个节点失效,导致其它节点的缓存命中率下降,缓存中缺失的数据直接去数据库查询,短时间内造成数据库服务器崩溃. 或者是由于缓存周期性失效,比如设置每隔6个小时失效一次,那么每6个 ...

  7. leetcode36

    public class Solution { public bool IsValidSudoku(char[,] board) { ; i < ; i++) { var dic = new D ...

  8. 「小程序JAVA实战」小程序我的个人信息页面开发(41)

    转自:https://idig8.com/2018/09/05/xiaochengxujavashizhanxiaochengxuwodegerenxinxiyemiankaifa40/ 已经完成了登 ...

  9. ATL接口返回类型&&ATL接口返回字符串BSTR*

    感觉在ATL中做COM组件,添加方法的时候,其返回值只能是HRESULT,我想返回其他数据类型,可以吗? 非也非也 HRESULT指示返回的状态,即正确与否, 返回值是这样的 HRESULT MyMe ...

  10. 谈谈跨平台的app开发 坚定的选择了flutter

    目前市场上,(市场也许用的不对),比较常见的技术有xamrin.RN.Flutter,确切的说flutter是后起之秀,笔者也是最近才开始学习,xamrin是微软系的技术,笔者也很早就开始学习了,RN ...