.Net Core定时任务 Hangfire 和 Quartz 2大框架的基本使用
起因
公司刚转型Core 要做定时任务监听FTP服务器文件,读取存入数据库,百度一大堆Quartz 和 Hangfire 没有一个注入服务的事例
千篇一律的Copy,让我这个新手感觉厌恶。
找了2位大佬 JoyLing 和 DX 还有其他大佬的指点 总算搞出来自己满意的代码了
源码
本人写的一个.Net Core 和 Angular的框架 事例都会在里面展现
后台:https://github.com/HDONGDeveloper/BasisSoa
前端:https://github.com/HDONGDeveloper/BasisSoa-Alain
定时器 Hangfire 1.6.21(最低1分钟任务起步)
这个框架配置简单 而且自带界面给人感觉非常舒服直接看代码吧
首先基本流程
在 Statup =》 ConfigureServices 加入 services.AddHangfire(r => r.UseSqlServerStorage(数据库连接字符串)); //因为Hangfire 的图形化界面需要数据表的支撑 在 Statup =》 Configure 加入 //定时任务 var jobOption = new BackgroundJobServerOptions { WorkerCount = 5//并发数 }; app.UseHangfireServer(jobOption); app.UseHangfireDashboard();
然后就是加入执行计划 很多朋友如果用 Hangfire 把计划任务放在 Controllers控制器的话 可能会造成服务器必须开启 ip/hangfire页面 才能执行计划
对于这个问题 我们用BackgroundService
namespace BasisSoa.Api.Hangfire { public class HangfireService : BackgroundService { ISysLogService sysLogService; //这是我测试能否注入我的Service层 public HangfireService(ISysLogService _sysLogService) { sysLogService = _sysLogService; } public override async Task StartAsync(CancellationToken cancellationToken) { RecurringJob.AddOrUpdate("Time_LogTime", () => Console.WriteLine("12"), Cron.MinuteInterval(1)); } protected override Task ExecuteAsync(CancellationToken stoppingToken) { throw new NotImplementedException(); } } }
在Starup注入
services.AddHostedService<HangfireService>(); //注入服务
然后启动项目 连接/hangfire/ 愉快的去看效果就行
定时器 Quartz 3.0.7
这个框架相对于 hangfire要比较复杂但是可以实现分钟以下的 调用
基本流程还是服务注入
在 Statup =》 ConfigureServices services.AddSingleton<IJobFactory, JobFactorys>(); //Job工厂 services.AddTransient<hellJob>(); //计划任务 services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();//注册ISchedulerFactory的实例
services.AddSingleton(p => {
var sf = new StdSchedulerFactory();
var scheduler = sf.GetScheduler().Result;
scheduler.JobFactory = p.GetService<IJobFactory>();
return scheduler;
});//注册ISchedulerFactory的实例。
services.AddHostedService<QuartzService>(); //注入服务
JobFactorys工厂产生IJob
public class JobFactorys: IJobFactory { private readonly IServiceProvider _serviceProvider; public JobFactorys(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { try { var job = _serviceProvider.GetService(bundle.JobDetail.JobType) as IJob; return job; } catch (Exception e) { //NLogHelper.Error(e); } return null; } public void ReturnJob(IJob job) { } }
计划任务
public class hellJob : IJob { private readonly ITResponseXmlService _xmlcontentService; //这是我的服务层测试能否注入 public hellJob(ITResponseXmlService xmlcontentService) { _xmlcontentService = xmlcontentService; Console.Out.WriteLineAsync("Greetings from HelloJob!"); } public async Task Execute(IJobExecutionContext context) { //_xmlcontentService = context.JobDetail.Key.Name await _xmlcontentService.DownloadFtp(); await Console.Out.WriteLineAsync("Greetings from HelloJob!"); } }
启动注入服务
public class QuartzService : BackgroundService { private readonly IScheduler _scheduler; private readonly IServiceProvider _serviceProvider; public QuartzService(IScheduler scheduler, IServiceProvider serviceProvider) { _scheduler = scheduler; _serviceProvider = serviceProvider; } public override async Task StartAsync(CancellationToken cancellationToken) { DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(DateTime.Now, 1); DateTimeOffset endTime = DateBuilder.NextGivenMinuteDate(DateTime.Now, 10); IJobDetail job = JobBuilder.Create<hellJob>() .WithIdentity("job", "group") .Build(); ICronTrigger cronTrigger = (ICronTrigger)TriggerBuilder.Create() .StartAt(startTime) .EndAt(endTime) .WithIdentity("job", "group") .WithCronSchedule("*/5 * * * * ?") .Build(); await _scheduler.ScheduleJob(job, cronTrigger); await _scheduler.Start(cancellationToken); } public override async Task StopAsync(CancellationToken cancellationToken) { await _scheduler.Shutdown(cancellationToken); } protected override Task ExecuteAsync(CancellationToken stoppingToken) { throw new NotImplementedException(); } }