from:https://blogs.msdn.microsoft.com/scott_hanselman/2014/12/21/asp-net/

[原文发表地址] How to run Background Tasks in ASP.NET

[原文发表时间] 2014-08-26

几年前,Phil Haack写了一篇关于ASP.NET中定期后台任务存在的隐患的优秀文章。他指出了一些人们在后台工作时常见的陷阱。您可阅读这篇文章,下面是他帖子里得出的摘要。

  • 在一个线程中,一个与需求不相关的未处理异常将会终止该进程。
  • 如果你在一个Web Farm中运行网站,你大概会以你的应用程序里,试图在同一时间运行同样任务的多个实例结束。
  • 在AppDomain中运行你的网站会因为种种原因而终止,且后台任务也会随之一起终止。

如果你认为你可以自己写一个后台任务,很可能你会进去误区。我并非怀疑你的技术,只能说这太微妙了。而且,你为什么非要这样做呢?

有很多种方式可以让你在后台工作,有很多资源库和选择可利用。

一些ASP.NET应用程序会承载于你的IIS数据中心里,其他的则将承载于在Azure 云上。在我看来,利用率的频谱大致是这样:

  • 通用方法:Hangfire(或者类似的开源资源库)

用于ASP.NET网站上编写后台任务。

一个正规的Azure功能,用来卸载运行于网站之外的后台任务和度量工作量。

快速测量网站后台进程的数量,并 且你需要调度这些机器。

有很多介绍如何使用Azure WebJobs的优秀文章和视频,也有很多介绍工作者角色是如何在可扩展的Azure云服务中工作的文档,但是介绍关于如何承载ASP.NET应用程序和轻松拥有一个后台服务的不多。这里列举了一些。

WebBackgrounder
正如它所说的“WebBackgrounder是一个web-farm,友好的后台任务管理器的概念证明,意味着它仅仅与一个普通的ASP.NET web应用程序协作。”多年来,它的代码没有公开,但是WebBackgrounder NuGet 包已经被下载了大约50万次。

这个项目的目的是处理一个任务,在web应用程序的后台时间间隔管理一个循环的任务。

如果你的ASP.NET应用程序仅仅需要一个后台任务来运行一个基本的预定时间间隔,那么你可能需要基本的WebBackgrounder知识。

  1. using System;
  1. using System.Threading;
  1. using System.Threading.Tasks;
  1. namespace WebBackgrounder.DemoWeb
  1. {
  1. public class SampleJob : Job
  1. {
  1. public SampleJob(TimeSpan interval, TimeSpan timeout)
  1. : base("Sample Job", interval, timeout)
  1. {
  1. }
  1. public override Task Execute()
  1. {
  1. return new Task(() => Thread.Sleep(3000));
  1. }
  1. }
  1. }
  1. 建立:QueueBackgroundWorkItem-加入.NET4.5.2
  1. 在某种程度上对WebBackgrounder的需产生影响,QueueBackgroundWorkItem作为一个新的API被添加于.NET 4.5.2 。它不只是一个”Task.Run”,它的功能还有很多:

QBWI预设了一个可以在后台运行的任务,它独立于任何需求。这不同于平常的ASP.NET线程池工作项,ASP.NET自动记录有多少个通过API注册的工作项正在运行,并且ASP.NET运行时会延迟AppDomain的关闭,直到工作项停止执行。

为了保证任务完成,它可以延迟AppDomain关闭长达90秒。如果你在90秒内无法完成,那么你需要一个不同的(更健壮的,更有意义的,进程以外的)技术。

这个API非常简单,使用Func<CancellationToken, Task>。这里有一个从MVC截取的后台工作项例子:

  1. public ActionResult SendEmail([Bind(Include = "Name,Email")] User user)
  1. {
  1. if (ModelState.IsValid)
  1. { HostingEnvironment.QueueBackgroundWorkItem(ct => SendMailAsync(user.Email));
  1. return RedirectToAction("Index", "Home");
  1. }
  1. return View(user);
  1. }

FluentScheduler

FluentScheduler 是一个更精密和复杂的调度程序,它有一个(如你所想)流畅的界面。当你的任务运行时你是真正地显式控制。

  1. using FluentScheduler;
  1. public class MyRegistry : Registry
  1. {
  1. public MyRegistry()
  1. { // Schedule an ITask to run at an interval
  1. Schedule<MyTask>().ToRunNow().AndEvery(2).Seconds();
  1. // Schedule a simple task to run at a specific time
  1. Schedule(() => Console.WriteLine("Timed Task - Will run every day at 9:15pm: " + DateTime.Now)).ToRunEvery(1).Days().At(21, 15);
  1. // Schedule a more complex action to run immediately and on an monthly interval
  1. Schedule(() =>
  1. {
  1. Console.WriteLine("Complex Action Task Starts: " + DateTime.Now);
  1. Thread.Sleep(1000);
  1. Console.WriteLine("Complex Action Task Ends: " + DateTime.Now);
  1. }).ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0);
  1. }
  1. }

FluentScheduler 也接受IoC,而且可以通过执行ItaskFactory界面来注入你喜欢的Dependency Injection tool。

Quartz.NET

Quartz.NET是一个拥有和流行的Java 工作调度框架(几乎)相同的名字的.NET端口。它得到了快速地发展。Quartz有一个IJob界面,只有一个用来执行的

  1. using Quartz;
  1. using Quartz.Impl;
  1. using System;
  1. namespace ScheduledTaskExample.ScheduledTasks
  1. {
  1. public class JobScheduler
  1. {
  1. public static void Start()
  1. {
  1. IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
  1. scheduler.Start();
  1. IJobDetail job = JobBuilder.Create<MyJob>().Build();
  1. ITrigger trigger = TriggerBuilder.Create()
  1. .WithDailyTimeIntervalSchedule
  1. (s =>
  1. s.WithIntervalInHours(24)
  1. .OnEveryDay()
  1. .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
  1. )
  1. .Build();
  1. scheduler.ScheduleJob(job, trigger);
  1. }
  1. }
  1. }

然后,在你的应用程序开始之前,你可以调用 JobScheduler.Start()。在Mikesdotnetting上面有一篇关于Quartz启动的优秀文章,你可以查阅。

Hangfire

最后但绝对不是最不重要的是,最优秀的(IMHO)组Hangfire 依从 @odinserj。 它是一个ASP.NET中后台工作极好的框架。为了保证可靠性,它甚至被Redis, SQL Server, SQL Azure, MSMQ, 或 RabbitMQ选择为坚强的后盾。

Hangfire的文档编制真的很神奇。每一个开源项目的文件应该像它这样。ASP.NET的文档编制也应该像它这么好。

Hangfire中最佳的功能是它建立了/hangfire 仪表板,向你展示所有预设的,加工中的,成功的和失败的进程。这真是一个很好的附加功能。

你可以轻易地把“fire和forget”工作加入队列并且它们是支持持久队列的:

BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget"));

你可以使用延迟…

BackgroundJob.Schedule(() => Console.WriteLine("Delayed"), TimeSpan.FromDays(1));

或者使用大而复杂的CRON风格的循环性任务:

RecurringJob.AddOrUpdate(() => Console.Write("Recurring"), Cron.Daily);

Hangfire是很有趣的。

查阅Hangfire 高亮教程可以看到一些复杂的但容易遵循现实世界的例子。

这是一个丰富的资源系统,可以帮助你完成后台任务。所有这些资源库都是卓越的,开源的,并且是可用作NuGet 包的。

我有遗漏你最喜欢的部分吗?如果有请在评论板中提出来!

在ASP.NET中如何运行后台任务的更多相关文章

  1. ASP.NET Core中的运行状况检查

    由卢克·莱瑟姆和格伦Condron ASP.NET Core提供了运行状况检查中间件和库,用于报告应用程序基础结构组件的运行状况. 运行状况检查由应用程序公开为HTTP终结点.可以为各种实时监视方案配 ...

  2. ASP.NET中HttpApplication中ProcessRequest方法中运行的事件顺序;ASP.NET WebForm和MVC总体请求流程图

    ASP.NET中HttpApplication中ProcessRequest方法中运行的事件顺序 1.BeginRequest  開始处理请求 2.AuthenticateRequest 授权验证请求 ...

  3. 微服务中的健康监测以及其在ASP.NET Core服务中实现运行状况检查

    1 .什么是健康检查? 健康检查几乎就是名称暗示的.它是一种检查您的应用程序是否健康的方法.随着越来越多的应用程序转向微服务式架构,健康检查变得尤其重要(Health Check).虽然微服务架构有很 ...

  4. 如何在 ASP.NET 应用程序中实现模拟用户身份(在ASP.NET中以管理员身份运行网站)

    前言 在实际的项目开发中,我们可能会需要调用一些非托管程序,而有些非托管程序需要有更高的身份权限才能正确执行.本文介绍了如何让IIS承载的ASP.NET网站以特定的账户执行,比如Administrat ...

  5. ASP.NET Core托管运行Quartz.NET作业调度详解

    Quartz.NET这么NB的作业调度系统,不会还行?   今天介绍一下Quartz.NET的托管运行,官网传送门. 一.前言 Quartz.NET,按官网上的说法,是一款功能齐全的任务调度系统,从小 ...

  6. ASP.NET中常用的优化性能的方法

    1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池( ...

  7. ASP.NET中Session的sessionState 4种mode模式

    1. sessionState的4种mode模式 在ASP.NET中Session的sessionState的4中mode模式:Off.InProc.StateServer及SqlServer. 2. ...

  8. ASP.NET中后台数据和前台控件的绑定

    关于ASP.NET中后台数据库和前台的数据控件的绑定问题 最近一直在学习个知识点,自己创建了SQL Server数据库表,想在ASP.NET中连接数据库,并把数据库中的数据显示在前台,注意,这里的数据 ...

  9. Asp.net中static变量和viewstate的使用方法(谨慎)

    在.Net平台下进行CS软件开发时,我们经常遇到以后还要用到某些变量上次修改后的值,为了简单起见,很多人都习惯用static来定义这些变量,我也是.这样非常方便,下一次调用某个函数时该变量仍然保存的是 ...

随机推荐

  1. ReactiveCocoa基础知识内容

    本文记录一些关于学习ReactiveCocoa基础知识内容,对于ReactiveCocoa相关的概念如果不了解可以网上搜索:RACSignal有很多方法可以来订阅不同的事件类型,ReactiveCoc ...

  2. 【代码笔记】iOS-给背景图赋值颜色

    代码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. // ...

  3. 【Android】不依赖焦点和选中的TextView跑马灯【2】

    前言 之前有写一篇TextView跑马灯的效果,后来实际项目中有发现新的问题,比如还是无法自动跑,文本超过了显示区域就截取的问题,今天换了一种思路来实现,更简单更好用. 声明 欢迎转载,但请保留文章原 ...

  4. android 数据存储Ⅱ

    本章继续讲解在Android开发中,数据的存储与管理.涉及知识点:SQLite,SwipeRefreshLayout控件刷新. 1.功能需求 练习使用SQLite 做一个登录界面,数据库字段包含用户名 ...

  5. 关于Linux与windows传递文件乱码问题

    linux下一般是采用utf-8的编码,而我们在windows上编辑文件时是gb2312的编码.所以导致中文编码会乱码.要更正这个问题实际上很简单只要把文件转换成utf-8编码格式然后再导入就ok啦. ...

  6. 学习 jsonp

    1.起因 js脚本做ajax异步调用的时候,直接请求普通文件存在跨域无权限访问的问题,不管你是静态页面.动态网页.web服务,只要是跨域请求,都无法成功: 如果上句话没明白,我们直接看例子.有两个一模 ...

  7. github邮箱验证技巧

    申请的github账号,绑定邮箱之后才能创建库,而反复几次的发送邮件均为收到验证邮件,猜测有两个原因: 1.腾讯邮件服务器屏蔽了github的来信 (腾讯不会这么狭隘的,×) 2.自己邮箱的域名黑名单 ...

  8. 系统吞吐量、TPS(QPS)、用户并发量、性能测试概念和公式

    PS:下面是性能测试的主要概念和计算公式,记录下: 一.系统吞度量要素: 一个系统的吞度量(承压能力)与request对CPU的消耗.外部接口.IO等等紧密关联.单个reqeust 对CPU消耗越高, ...

  9. ORACLE 10g AWR报告设置总结

      1:查看.修改AWR报告快照数据的采样间隔.保存策略 SQL> COL DBID FOR 999999999999 SQL> COL SNAP_INTERVAL FOR A26 SQL ...

  10. [转载]DBA的特质第二部分:性格

    本文转自http://www.searchdatabase.com.cn/showcontent_84382.htm 支持原创.尊重原创,分享知识! 在本系列文章中,笔者将谈一谈数据库管理员(DBA) ...