如何在ASP.NET中运行后台任务

A few years back Phil Haack wrote a great article on the dangers of recurring background tasks in ASP.NET. In it he points out a few gotchas that are SO common when folks try to do work in the background. Read it, but here's a summary from his post.

几年前,Phil Haack写了一篇很棒的文章,谈到了ASP.NET中重复执行后台任务的危险。 他在其中指出了一些人们在后台尝试工作时很常见的陷阱。 阅读它,但这是他的帖子的摘要。

  • An unhandled exception in a thread not associated with a request will take down the process.

    与请求不相关联的线程中未处理的异常将导致进程中断。
  • If you run your site in a Web Farm, you could end up with multiple instances of your app that all attempt to run the same task at the same time.

    如果在Web场中运行站点,则最终可能会遇到多个应用程序实例,所有这些实例都试图同时运行同一任务。
  • The AppDomain your site runs in can go down for a number of reasons and take down your background task with it.

    您的网站在其中运行的AppDomain可能会由于多种原因而关闭,并随之终止您的后台任务。

If you think you can just write a background task yourself, it's likely you'll get it wrong. I'm not impugning your skills, I'm just saying it's subtle. Plus, why should you have to?

如果您认为自己可以自己编写一个后台任务,则很可能会弄错它。 我不是在削弱你的技能,我只是说这很微妙。 另外,为什么要这么做?

There's LOT of great ways for you to do things in the background and a lot of libraries and choices available.

有很多很棒的方法可以让您在后台执行操作,并且有很多可用的库和选项。

Some ASP.NET apps will be hosted in IIS in your data center and others will be hosted in the Azure cloud. The spectrum of usage is roughly this, in my opinion:

一些ASP.NET应用程序将托管在数据中心的IIS中,而其他应用程序将托管在Azure云中。 我认为用法范围大致如下:

There's lots of great articles and videos on how to use Azure WebJobs, and lots of documentation on how Worker Roles in scalable Azure Cloud Services work, but not a lot about how your hosted ASP.NET application and easily have a background service. Here's a few.

关于如何使用Azure WebJobs的文章和视频很多,关于可伸缩Azure Cloud Services中的工作人员角色的工作方式的文档也很多,但是关于托管ASP.NET应用程序的方式以及轻松拥有后台服务的内容却很少。 这是一些。

Web背景 (WebBackgrounder)

As it says "WebBackgrounder is a proof-of-concept of a web-farm friendly background task manager meant to just work with a vanilla ASP.NET web application." Its code hasn't been touched in years, BUT the WebBackgrounder NuGet package has been downloaded almost a half-million times.

正如它所说的那样:“ WebBackgrounder是对Web农场友好的后台任务管理器的概念验证,旨在仅与普通的ASP.NET Web应用程序一起工作。” 它的代码多年没有被触及过,但是WebBackgrounder NuGet软件包已被下载了近50万次。

The goal of this project is to handle one task only, manage a recurring task on an interval in the background for a web app.

该项目的目标是仅处理一项任务,在Web应用程序的后台按一定间隔管理重复执行的任务。

If your ASP.NET application just needs one background task to runs an a basic scheduled interval, than perhaps you just need the basics of WebBackgrounder.

如果您的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-在.NET 4.5.2中添加 (Built in: QueueBackgroundWorkItem - Added in .NET 4.5.2)

Somewhat in response to the need for WebBackgrounder, .NET 4.5.2 added QueueBackgroundWorkItem as a new API. It's not just a "Task.Run," it tries to be more:

.NET 4.5.2为了响应WebBackgrounder的需要,添加了QueueBackgroundWorkItem作为新的API 。 它不仅仅是一个“ Task.Run”,它还会尝试更多:

QBWI schedules a task which can run in the background, independent of any request. This differs from a normal ThreadPool work item in that ASP.NET automatically keeps track of how many work items registered through this API are currently running, and the ASP.NET runtime will try to delay AppDomain shutdown until these work items have finished executing.

QBWI计划可以独立于任何请求在后台运行的任务。 这不同于正常的ThreadPool工作项,因为ASP.NET自动跟踪当前正在运行通过此API注册的工作项的数量,并且ASP.NET运行时将尝试延迟AppDomain关闭,直到这些工作项执行完毕。

It can try to delay an AppDomain for as long as 90 seconds in order to allow your task to complete. If you can't finish in 90 seconds, then you'll need a different (and more robust, meaning, out of process) technique.

它可以尝试将AppDomain延迟90秒,以使您的任务完成。 如果您不能在90秒内完成操作,那么您将需要一种不同的技术(并且更加健壮,这意味着超出流程)。

The API is pretty straightforward, taking  Func<CancellationToken, Task>. Here's an example that kicks of a background work item from an MVC action:

该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 is a more sophisticated and complex scheduler that features a (you guessed it) fluent interface. You have really explicit control over when your tasks run.

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 also embraces IoC and can easily plug into your favorite Dependency Injection tool of choice by just implementing their ITaskFactory interface.

FluentScheduler还包含IoC,并且只需实现其ITaskFactory接口即可轻松插入您喜欢的依赖注入工具。

Quartz.NET (Quartz.NET)

Quartz.NET is a .NET port of the popular Java job scheduling framework of the (almost) same name. It's very actively developed. Quartz has an IJob interface with just one method, Execute, to implement.

Quartz.NET是(几乎)同名的流行Java作业调度框架的.NET端口。 它是非常积极的发展。 Quartz有一个IJob接口,只有一种方法Execute可以实现。

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);
}
}
}

Then, inside your Application_Start, you call JobScheduler.Start(). There's a great getting started article on Quartz at Mikesdotnetting you should check out.

然后,在Application_Start内部,调用JobScheduler.Start()。 Mikesdotnetting上一篇关于Quartz很棒的入门文章,您应该看看。

吊火 (Hangfire)

And last but definitely not least, the most polished (IMHO) of the group, Hangfire by @odinserj. It's a fantastic framework for background jobs in ASP.NET. It's even optionally backed by Redis, SQL Server, SQL Azure, MSMQ, or RabbitMQ for reliability.

最后但并非最不重要的一点是,该组中最出色的(IMHO), @ odinserjHangfire 。 这是ASP.NET中用于后台作业的理想框架。 为了提高可靠性,它甚至还可以选择由Redis,SQL Server,SQL Azure,MSMQ或RabbitMQ支持。

The Hangfire documentation is amazing, really. Every open source project's document should be this polished. Heck, ASP.NET's documentation should be this good.

Hangfire文档确实很棒。 每个开源项目的文档都应该如此完善。 哎呀,ASP.NET的文档应该很好。

The best feature from Hangfire is its built in /hangfire dashboard that shows you all your scheduled, processing, succeeded and failed jobs. It's really a nice polished addition.

Hangfire的最佳功能是其内置的/ hangfire仪表板,可向您显示所有计划的,正在处理的,成功的和失败的作业。 这确实是一个不错的补充。

image

You can enqueue "fire and forget" jobs easily and they are backed by persistent queues:

您可以轻松地将“即发即弃”的工作加入队列,并且这些工作由持久队列支持:

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

You can delay them...

您可以延迟...

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

Or great very sophisticated CRON style recurrent tasks:

或非常复杂的CRON样式重复任务:

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

Hangfire is just a joy.

Hangfire只是一种乐趣。

Check out the Hangfire Highlighter Tutorial for a sophisticated but easy to follow real-world example.

请查看Hangfire荧光笔教程,以获取复杂但易于遵循的真实示例。

There's a rich ecosystem out there ready to help you with your background tasks. All these libraries are excellent, are open source, and are available as NuGet Packages.

那里有一个丰富的生态系统,随时可以帮助您完成后台任务。 所有这些库都是优秀的,是开源的,并且可以作为NuGet Packages获得

Did I miss your favorite? Sound off in the comments!

我想念你的最爱吗? 在评论中听起来不错!

翻译自: https://www.hanselman.com/blog/how-to-run-background-tasks-in-aspnet

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值