来源:seabluescn
cnblogs.com/seabluescn/p/9405439.html
源码下载地址:https://github.com/seabluescn/Blog_WebApi
一、概述
本篇介绍在ASP.NET Core中实现定时任务,使用的组件为Hangfire,hangfire的时间最小粒度为分钟,不能到秒,但自带一个可视化控制台,可以通过页面方式查看任务执行情况。
除了实现定时任务,还可以使用该框架实现一个耗时任务,比如短信发送,应用业务在发送短信时启动短信发送任务,然后就可以立即返回,无需等待,由短信发送任务实现冗长的通信过程,如果该过程发生了异常,框架会重新调用该任务。
二、环境
通过NuGet引用下面几个包,如果不需要持久化,可以不要MySQL和Redis相关的包。
三、基本使用方法
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddHangfire(x => x.UseStorage(new MemoryStorage()));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.UseHangfireServer();
app.UseHangfireDashboard();
RecurringJob.AddOrUpdate(() => Console.WriteLine("hello"), Cron.Minutely());
}
}
如果要考虑持久化,推荐使用Redis,比使用MySQL快很多。
//Redis
var connectionString = "50.220.197.198:1987,allowAdmin=true,password=,defaultdatabase=10";
services.AddHangfire(x => x.UseRedisStorage(connectionString));
//MySQL
var connectionString = "Server=50.220.197.198;port=3317;database=hangfire;uid=hf;pwd=hf207;SslMode=None;Allow User Variables=true;";
services.AddHangfire(x => x.UseStorage(new MySqlStorage(connectionString)));
其他代码不变。
四、启动任务
最简单的办法,一行代码就启动了一个循环任务:
RecurringJob.AddOrUpdate(() => Console.WriteLine("hello"), Cron.Minutely());
但实际应用时,不会就一行代码的,所以,我们建一个类来存放定时任务。通过调用对象的方法来启动定时任务:
TimedTaskService service = new TimedTaskService();
RecurringJob.AddOrUpdate(() => service.SendMessage(), Cron.Minutely());
TimedTaskService类的定义如下:
public class TimedTaskService
{
[DisplayName("SendMessage")]
public void SendMessage()
{
Console.WriteLine($":SendMessage working!");
Thread.Sleep(new Random().Next(50) * 100);
}
}
我们还可以在Controller中启动一个任务:
[Route("api/[controller]")]
public class ValuesController : Controller
{
[HttpGet("do1")]
public string GetDo1()
{
BackgroundJob.Enqueue(t => t.DoSomeThing1());
return "success";
}
}
TimedTaskService类的定义如下:
public class TimedTaskService
{
public void DoSomeThing1()
{
Console.WriteLine("DoSomeThing1:我只执行一次,但时间比较长");
int time = 10+new Random().Next(20);
Thread.Sleep(time * 1000);
}
}
以上通过RecurringJob实现定时任务,通过BackgroundJob实现一次性任务。
五、关于定时任务的周期
Cron方法的调用,返回一个字符串,这里可以不使用Cron方法,直接写字符串,建议使用Cron方法,不容易出错。
一些Cron方法对应的字符串如下:
详细的Cron知识请参考相关资料,这里不详细描述。
这里还要特别注意一个时区的问题,下面的代码不会按希望的时间执行:
RecurringJob.AddOrUpdate(() => service.SendMessage(), "10 3 * * *");
需要改成如下代码:
RecurringJob.AddOrUpdate(() => service.SendMessage(), "10 3 * * *", TimeZoneInfo.Local);
六、任务可视化
通过http://localhost:5000/hangfire可以访问可视化面板,该页面的访问权限问题可以通过用户认证中间件来解决。
看完本文有收获?请转发分享给更多人
关注「DotNet」,提升.Net技能