在ASP.NET中如何运行后台任务
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 WebJobs
一个正规的Azure功能,用来卸载运行于网站之外的后台任务和度量工作量。
- 高级方法:云服务执行器
快速测量网站后台进程的数量,并 且你需要调度这些机器。
有很多介绍如何使用Azure WebJobs的优秀文章和视频,也有很多介绍工作者角色是如何在可扩展的Azure云服务中工作的文档,但是介绍关于如何承载ASP.NET应用程序和轻松拥有一个后台服务的不多。这里列举了一些。
WebBackgrounder
正如它所说的“WebBackgrounder是一个web-farm,友好的后台任务管理器的概念证明,意味着它仅仅与一个普通的ASP.NET web应用程序协作。”多年来,它的代码没有公开,但是WebBackgrounder NuGet 包已经被下载了大约50万次。
这个项目的目的是处理一个任务,在web应用程序的后台时间间隔管理一个循环的任务。
如果你的ASP.NET应用程序仅仅需要一个后台任务来运行一个基本的预定时间间隔,那么你可能需要基本的WebBackgrounder知识。
using System;
using System.Threading;
using System.Threading.Tasks;
namespace WebBackgrounder.DemoWeb
{
public class SampleJob : Job
{
public SampleJob(TimeSpan interval, TimeSpan timeout)
: base("Sample Job", interval, timeout)
{
}
public override Task Execute()
{
return new Task(() => Thread.Sleep(3000));
}
}
}
建立:QueueBackgroundWorkItem-加入.NET4.5.2
在某种程度上对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截取的后台工作项例子:
public ActionResult SendEmail([Bind(Include = "Name,Email")] User user)
{
if (ModelState.IsValid)
{ HostingEnvironment.QueueBackgroundWorkItem(ct => SendMailAsync(user.Email));
return RedirectToAction("Index", "Home");
}
return View(user);
}
FluentScheduler 是一个更精密和复杂的调度程序,它有一个(如你所想)流畅的界面。当你的任务运行时你是真正地显式控制。
using FluentScheduler;
public class MyRegistry : Registry
{
public MyRegistry()
{ // Schedule an ITask to run at an interval
Schedule<MyTask>().ToRunNow().AndEvery(2).Seconds();
// Schedule a simple task to run at a specific time
Schedule(() => Console.WriteLine("Timed Task - Will run every day at 9:15pm: " + DateTime.Now)).ToRunEvery(1).Days().At(21, 15);
// Schedule a more complex action to run immediately and on an monthly interval
Schedule(() =>
{
Console.WriteLine("Complex Action Task Starts: " + DateTime.Now);
Thread.Sleep(1000);
Console.WriteLine("Complex Action Task Ends: " + DateTime.Now);
}).ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0);
}
}
FluentScheduler 也接受IoC,而且可以通过执行ItaskFactory界面来注入你喜欢的Dependency Injection tool。
Quartz.NET
Quartz.NET是一个拥有和流行的Java 工作调度框架(几乎)相同的名字的.NET端口。它得到了快速地发展。Quartz有一个IJob界面,只有一个用来执行的
using Quartz;
using Quartz.Impl;
using System;
namespace ScheduledTaskExample.ScheduledTasks
{
public class JobScheduler
{
public static void Start()
{
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Start();
IJobDetail job = JobBuilder.Create<MyJob>().Build();
ITrigger trigger = TriggerBuilder.Create()
.WithDailyTimeIntervalSchedule
(s =>
s.WithIntervalInHours(24)
.OnEveryDay()
.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(0, 0))
)
.Build();
scheduler.ScheduleJob(job, trigger);
}
}
}
然后,在你的应用程序开始之前,你可以调用 JobScheduler.Start()。在Mikesdotnetting上面有一篇关于Quartz启动的优秀文章,你可以查阅。
Hangfire
最后但绝对不是最不重要的是,最优秀的(IMHO)组Hangfire 依从 @odinserj。 它是一个ASP.NET中后台工作极好的框架。为了保证可靠性,它甚至被Redis, SQL Server, SQL Azure, MSMQ, 或 RabbitMQ选择为坚强的后盾。
Hangfire的文档编制真的很神奇。每一个开源项目的文件应该像它这样。ASP.NET的文档编制也应该像它这么好。
Hangfire中最佳的功能是它建立了/hangfire 仪表板,向你展示所有预设的,加工中的,成功的和失败的进程。这真是一个很好的附加功能。
![]()
你可以轻易地把“fire和forget”工作加入队列并且它们是支持持久队列的:
|
|
你可以使用延迟…
|
|
或者使用大而复杂的CRON风格的循环性任务:
|
|
Hangfire是很有趣的。
查阅Hangfire 高亮教程可以看到一些复杂的但容易遵循现实世界的例子。
这是一个丰富的资源系统,可以帮助你完成后台任务。所有这些资源库都是卓越的,开源的,并且是可用作NuGet 包的。
我有遗漏你最喜欢的部分吗?如果有请在评论板中提出来!
在ASP.NET中如何运行后台任务的更多相关文章
- ASP.NET Core中的运行状况检查
由卢克·莱瑟姆和格伦Condron ASP.NET Core提供了运行状况检查中间件和库,用于报告应用程序基础结构组件的运行状况. 运行状况检查由应用程序公开为HTTP终结点.可以为各种实时监视方案配 ...
- ASP.NET中HttpApplication中ProcessRequest方法中运行的事件顺序;ASP.NET WebForm和MVC总体请求流程图
ASP.NET中HttpApplication中ProcessRequest方法中运行的事件顺序 1.BeginRequest 開始处理请求 2.AuthenticateRequest 授权验证请求 ...
- 微服务中的健康监测以及其在ASP.NET Core服务中实现运行状况检查
1 .什么是健康检查? 健康检查几乎就是名称暗示的.它是一种检查您的应用程序是否健康的方法.随着越来越多的应用程序转向微服务式架构,健康检查变得尤其重要(Health Check).虽然微服务架构有很 ...
- 如何在 ASP.NET 应用程序中实现模拟用户身份(在ASP.NET中以管理员身份运行网站)
前言 在实际的项目开发中,我们可能会需要调用一些非托管程序,而有些非托管程序需要有更高的身份权限才能正确执行.本文介绍了如何让IIS承载的ASP.NET网站以特定的账户执行,比如Administrat ...
- ASP.NET Core托管运行Quartz.NET作业调度详解
Quartz.NET这么NB的作业调度系统,不会还行? 今天介绍一下Quartz.NET的托管运行,官网传送门. 一.前言 Quartz.NET,按官网上的说法,是一款功能齐全的任务调度系统,从小 ...
- ASP.NET中常用的优化性能的方法
1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池( ...
- ASP.NET中Session的sessionState 4种mode模式
1. sessionState的4种mode模式 在ASP.NET中Session的sessionState的4中mode模式:Off.InProc.StateServer及SqlServer. 2. ...
- ASP.NET中后台数据和前台控件的绑定
关于ASP.NET中后台数据库和前台的数据控件的绑定问题 最近一直在学习个知识点,自己创建了SQL Server数据库表,想在ASP.NET中连接数据库,并把数据库中的数据显示在前台,注意,这里的数据 ...
- Asp.net中static变量和viewstate的使用方法(谨慎)
在.Net平台下进行CS软件开发时,我们经常遇到以后还要用到某些变量上次修改后的值,为了简单起见,很多人都习惯用static来定义这些变量,我也是.这样非常方便,下一次调用某个函数时该变量仍然保存的是 ...
随机推荐
- Service和Thread的关系及如何启用Service,如何停用Service
Service和Thread的关系: 不少Android初学者都可能会有这样的疑惑,Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案可能会 ...
- 运算符&,|,^
1.&按位“与”的计算是把两个数字分别写成二进制形式,然后按照每一位进行比较,&计算中,只要有一个是0就算成02.|运算转换成2进制进行比较,两个位只要有一个为1,那么结果就是1,否则 ...
- iOS关于CAShapeLayer与UIBezierPath的知识内容
使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形 . 1:UIBezierPath: UIBezierPath是在 UIKit 中 ...
- Facebook开源动画库 POP-POPBasicAnimation运用
动画在APP开发过程中还是经常出现,将花几天的时间对Facebook开源动画库 POP进行简单的学习:本文主要针对的是POPBasicAnimation运用:实例源代码已经上传至gitHub,地址:h ...
- postgresql function 返回 select
pq函数功能很强大,我打算把统计的功能都放在数据库端.优势让运算离数据更近一些,缺点无法服用代码.牺牲了django的灵魂性,项目必须依赖postgresql. 项目中,希望实现返回select内容 ...
- SQL Server日期时间格式转换字符串
在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的.本文我们主要就介绍一下SQL Server日 ...
- nodejs events模块
var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); console.log(emi ...
- MyEclipse Servers视窗出现“Could not create the view: An unexpected exception was thrown”错误的解决办法
打开myeclipse所在的wordspace文件夹,在下面子文件夹 .metadata\.plugins\org.eclipse.core.runtime\.settings删除 com.genui ...
- Extjs插入图片
Extjs并没有提供直接的组件来显示图片.网上通过设置textfield的InputType为Image然后再修改dom对象来实现,其实 image的属性值并没有包含在Extjs的官方文档当中.可以通 ...
- ksvcreate: Process(m000) creation failed
一测试服务器数据库(Oracle Database 10g Release 10.2.0.5.0 - 64bit Production)突然访问不了,检查发现数据库处于挂起模式(hang mode), ...