稍微复杂一点的 web app 都会需要周期性执行一些工作。比如说,定时发邮件,目录同步,数据备份等。也许你会想,弄一个线程去后台执行后 sleep 不就行了?没错,我一开始也是这么干的!可惜理想是美好的,现实是骨感的,如果这个问题真是这么容易解决的话,那那么多调度框架还有存在的必要吗?

首先,需要考虑的 app 重启之后任务的持续性!比如说这个任务刚执行完,app 重启了,它就不应该马上执行。这涉及到持久化问题,也即是说要把任务执行情况写到磁盘,启动时判断。

其次,web app 最 CD 的是如果太久没人访问,那你悲剧了。IIS 会强制回收进程,等到下一次……下一次有人访问这个 web app 的时候再启动它!也就是说如果你的任务是在凌晨两三点进行的话,很可能它永远也不会被执行!

当然这两点都是可以解决的,但是既然有现成的轮子可以使用。我们又何必自己造轮子呢?更何况这个轮子有很多人在造,性能可能性也远比自己造的靠谱。

所以我们开始挑轮子。轮子不能随便搞一个就完事了,要根据自己的情况,比如说你是小客车,搞个挖土机的轮子装上去会出问题的,是吧。

说到任务调度,大家第一时间会想到 QuartZ.NET ,老牌框架,Java移植,有一万个理由选它。但我不喜欢太复杂的东西,相对来说,简单易理解,容易配置,灵活性好的工具更符合我的要求。

Hangfire

为什么选 Hangfire ?

1.当然它首先解决了我遇到的两个问题,支持数据库持久化,恶劣情况下还能保持任务能正常执行

支持各种数据库系统:Redis, SQL Server, SQL Azure, MSMQ, RabbitMQ

2.简单易懂,使用灵活

用完即弃:简单后台线程

BackgroundJob.Enqueue(() => Console.WriteLine("用完即弃"));

延时任务

BackgroundJob.Schedule(() => Console.WriteLine("延时任务"), TimeSpan.FromDays(1));

定期执行

RecurringJob.AddOrUpdate(() => Console.Write("定期执行"), Cron.Daily);

3.文档写得太棒了

下面是使用场景教程,一步一步相当详细,涉及的技术问题也一一讲解清楚。Scott Hanselman (ASP.NET Framework Programming人员) 盛赞:“ASP.NET的文档也应如此”

http://docs.hangfire.io/en/latest/tutorials/highlight.html

4.新生框架,没有太多历史包袱

历史遗留属于人力不可抗拒因素,像 QuartZ.NET 这种老牌框架,几乎是从 .NET 1.1 开始的?它再怎么努力也跳脱不了原来的设计理念。而现在 .NET 已经到了 4.5 ,语法,特性大不相同。新框架会首先考虑新语法新特性的使用。看下 Hangfire 的文档就知道, IDE 都是 vs2013 。

5.提供页面接口可以查看任务调试执行情况,成功的,失败的

image_0595e62a-c9fa-4a5e-a108-3931e1be22b0