设为首页 收藏本站
查看: 1116|回复: 0

[经验分享] 在ASP.NET中如何运行后台任务

[复制链接]

尚未签到

发表于 2017-7-1 12:58:59 | 显示全部楼层 |阅读模式
  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
  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 仪表板,向你展示所有预设的,加工中的,成功的和失败的进程。这真是一个很好的附加功能。

  你可以轻易地把&#8220;fire和forget&#8221;工作加入队列并且它们是支持持久队列的:
  BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget"));
  你可以使用延迟&#8230;
  BackgroundJob.Schedule(() => Console.WriteLine("Delayed"), TimeSpan.FromDays(1));
  或者使用大而复杂的CRON风格的循环性任务:
  RecurringJob.AddOrUpdate(() => Console.Write("Recurring"), Cron.Daily);
  Hangfire是很有趣的。
  查阅Hangfire 高亮教程可以看到一些复杂的但容易遵循现实世界的例子。
  这是一个丰富的资源系统,可以帮助你完成后台任务。所有这些资源库都是卓越的,开源的,并且是可用作NuGet 包的。
  我有遗漏你最喜欢的部分吗?如果有请在评论板中提出来!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-390013-1-1.html 上篇帖子: ElasticSearch入门 第五篇:使用C#查询文档 下篇帖子: SQL Server 2016最值得关注的10大新特性
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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