定时任务调度问题,是一个老生常谈的问题。网上有许多定时任务调度的解决方案,对于我而言很早以前主要是使用Window计划和Window服务来做任务定时执行,然后就开始使用定时任务调度框架Quartz.Net。但是却一直没有上手过Hangfire这个自带后台任务调度面板,可以在后台手动执行任务的神奇的任务调度框架。前段时间终于开始对他下手了,通过在网上查阅了一些资料和查看了Hangfire在Github中的demo,终于在我自己的项目中用上了Hangfire。在该篇文章中主要简单介绍一下什么是Hangfire,Hangfire的基本特征与优点和分别使用MySQL,MS SQL Server作为存储使用。
Hangfire是一个开源的.NET任务调度框架,提供了内置集成化的控制台,可以直观明了的查看作业调度情况,并且Hangfire不需要依赖于单独的应用程序执行(如:windows服务,window计划)。并且支持持久性存储。
Hangfire 不依赖于具体的.NET应用类型,包含.NET 和.NET Core。无需Windows服务/任务计划程序。
Hangfire的具有如下特性:
- 支持基于队列的任务处理:任务执行不是同步的,而是放到一个持久化队列中,以便马上把请求控制权返回给调用者。使用方法:BackgroundJob.Enqueue(() => Console.WriteLine(“Simple!”));
- 延迟任务执行:不是马上调用方法,而是设定一个未来时间点再来执行。使用方法:BackgroundJob.Schedule(() => Console.WriteLine(“Reliable!”), TimeSpan.FromDays(7));
- 循环任务执行:只需要简单的一行代码就可以添加重复执行的任务,其内置了常见的时间循环模式,也可以基于CRON表达式来设定复杂的模式。使用方法:RecurringJob.AddOrUpdate(() => Console.WriteLine(“Transparent!”), Cron.Daily);
Hangfire的具有如下有点:
- 持久化保存任务、队列、统计信息:默认使用SQL Server,也可以配合消息队列来降低队列处理延 迟,或配置使用Redis来获得更好的性能表现
- 内置自动重试机制:可以设定重试次数,还可以手动在控制台重启任务
除了调用静态方法外还支持实例方法能够捕获多语言状态:即可以把调用者的Thread.CurrentCulture和Thread.CurrentUICulture信息同任务持久保存在一起,以便任务执行的时候多语言信息是一致的- 支持任务取消:使用CancellationToken这样的机制来处理任务取消逻辑
- 支持IoC容器:目前支持Ninject和Autofac比较常用的开源IoC容器
- 支持Web集群:可以在一台或多台机器上运行多个Hangfire实例以便实现冗余备份
- 支持多队列:同一个Hangfire实例可以支持多个队列,以便更好的控制任务的执行方式
- 并发级别的控制:默认是处理器数量的5倍工作行程,当然也可以自己设定
- 具备很好的扩展性:有很多扩展点来控制持久存储方式、IoC容器支持等
为什么要使用Hangfire这样的函数库呢?
后台长时间的科学计算:
NetGet安装Hangfire
,Hangfire.SqlServer
注意,在控制台应用程序或者window server中不推荐直接安装:Install-Package Hangfire ,因为它只是一个快速启动软件包,并包含您可能不需要的依赖项(例如,Microsoft.Owin.Host.SystemWeb等无关依赖项)
MSMQ支持SQL Server作业存储实现,像其他Hangfire扩展一样,是一个NuGet包。您可以使用NuGet软件包管理器控制台窗口进行安装
Hangfire有这么几个表和索引来存储后台任务和相关的其他信息
static void Main(string[] args)
{
GlobalConfiguration.Configuration
.UseColouredConsoleLogProvider()
.UseSqlServerStorage("Server=.;User ID=sa;Password=123456;database=Zhao;");
//支持基于队列的任务处理:任务执行不是同步的,而是放到一个持久化队列中,以便马上把请求控制权返回给调用者。
// BackgroundJob.Enqueue(() => Console.WriteLine("Simple!"));
//延迟任务执行:不是马上调用方法,而是设定一个未来时间点再来执行。
// BackgroundJob.Schedule(() => Console.WriteLine("Reliable!"), TimeSpan.FromSeconds(5));
//循环任务执行:一行代码添加重复执行的任务,其内置了常见的时间循环模式,也可基于CRON表达式来设定复杂的模式。
RecurringJob.AddOrUpdate(() => Console.WriteLine("Transparent!"), Cron.Minutely);//注意最小单位是分钟
using (var server = new BackgroundJobServer())
{
BackgroundJob.Enqueue(() => Console.WriteLine("Simple111"));
Console.WriteLine("Hangfire Server started. Press any key to exit...");
Console.ReadKey();
}
//RecurringJob.AddOrUpdate(() => Test(), Cron.Minutely);
}
//写入作业
public static void Test()
{
//------
Console.WriteLine("");
}
Install-Package Hangfire
public void ConfigureServices(IServiceCollection services)
{
services.AddHangfire(r=>r.UseSqlServerStorage("Data Source=.;Initial Catalog=HangfireDemo;User ID=sa;Password=123456"));
}
然后在Configure 方法中加入HangfireServer及HangfireDashboard
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHangfireServer();
app.UseHangfireDashboard();
app.Run(context =>
{
return context.Response.WriteAsync("Hello from ASP.NET Core!");
});
}
访问地址:http://localhost:5000/hangfire
(也可以自定义路由,访问密码,具体参考官方文档)
app.Map("/index", r =>
{
r.Run(context =>
{
//任务每分钟执行一次
RecurringJob.AddOrUpdate(() => Console.WriteLine($"ASP.NET Core LineZero"), Cron.Minutely());
return context.Response.WriteAsync("ok");
});
});
Jobs 也就是查看所有的任务,我们可以在节目界面操作运行及删除,很方便。
官网地址:https://www.hangfire.io/
GitHub源码:https://github.com/HangfireIO/Hangfire
中文文档:https://www.bookstack.cn/read/Hangfire-zh-official/README.md
GitHub使用示例源码:https://github.com/HangfireIO/Hangfire.Samples(包括控制台应用程序,window服务,ASP.NET MVC,WebForm)
Hangfire使用文章汇总:https://www.bbsmax.com/R/xl56E0nrJr/
Hangfire使用参考:https://www.cnblogs.com/Leo_wl/p/5805287.html
Hangfire使用参考:https://www.cnblogs.com/owenzh/p/11623869.html