TimedTask使用进准的计时器方式而非轮训方式。
This commit is contained in:
parent
7350a60bb2
commit
2fec21a3ea
|
@ -10,16 +10,12 @@ namespace Falcon.SugarApi.TimedTask
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 由定时器驱动的后台任务
|
/// 由定时器驱动的后台任务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class TimedTask:BackgroundService, IDisposable
|
public abstract class TimedTask:BackgroundService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 日志记录器
|
/// 日志记录器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly ILogger? Logger;
|
protected readonly ILogger? Logger;
|
||||||
/// <summary>
|
|
||||||
/// 心跳计时器
|
|
||||||
/// </summary>
|
|
||||||
private readonly PeriodicTimer _timer;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 运行一次任务
|
/// 运行一次任务
|
||||||
|
@ -34,20 +30,11 @@ namespace Falcon.SugarApi.TimedTask
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected abstract string CronSchedule { get; }
|
protected abstract string CronSchedule { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Timer心跳 毫秒
|
|
||||||
/// </summary>
|
|
||||||
public virtual int Heartbeat { get; protected set; } = 1000;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取下次执行任务的计划
|
/// 获取下次执行任务的计划
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected CronExpression Schedule { get; private set; }
|
protected CronExpression Schedule { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 任务正在运行
|
|
||||||
/// </summary>
|
|
||||||
private bool _isRunning = false;
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下次执行时间
|
/// 下次执行时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -83,10 +70,6 @@ namespace Falcon.SugarApi.TimedTask
|
||||||
/// 系统服务
|
/// 系统服务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IServiceProvider Service { get; set; }
|
public IServiceProvider Service { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// 资源锁
|
|
||||||
/// </summary>
|
|
||||||
private static object _lock = new object();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造Timed后台任务
|
/// 构造Timed后台任务
|
||||||
|
@ -95,7 +78,6 @@ namespace Falcon.SugarApi.TimedTask
|
||||||
public TimedTask(IServiceProvider service) {
|
public TimedTask(IServiceProvider service) {
|
||||||
this.Service = service;
|
this.Service = service;
|
||||||
this.Logger = service.GetService(typeof(ILogger<>).MakeGenericType(GetType())) as ILogger;
|
this.Logger = service.GetService(typeof(ILogger<>).MakeGenericType(GetType())) as ILogger;
|
||||||
_timer = new PeriodicTimer(TimeSpan.FromMilliseconds(this.Heartbeat));
|
|
||||||
this.Schedule = new CronExpression(this.CronSchedule);
|
this.Schedule = new CronExpression(this.CronSchedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,49 +90,35 @@ namespace Falcon.SugarApi.TimedTask
|
||||||
if(!this.OnStart(this,stoppingToken)) {
|
if(!this.OnStart(this,stoppingToken)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while(await _timer.WaitForNextTickAsync(stoppingToken)) {
|
try {
|
||||||
lock(_lock) {
|
while(!stoppingToken.IsCancellationRequested) {
|
||||||
|
DateTime nextRunTime = Schedule.GetNextOccurrence(DateTime.Now);
|
||||||
|
TimeSpan delay = nextRunTime - DateTime.Now;
|
||||||
|
if(delay > TimeSpan.Zero) {
|
||||||
|
await Task.Delay(delay,stoppingToken);
|
||||||
|
}
|
||||||
if(stoppingToken.IsCancellationRequested) {
|
if(stoppingToken.IsCancellationRequested) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(this._isRunning) {
|
// 执行任务
|
||||||
continue;
|
try {
|
||||||
|
var goOn = await this.Run(stoppingToken);
|
||||||
|
var comResult = this.OnCompleted(this,stoppingToken);
|
||||||
|
if(!goOn || !comResult) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(DateTime.Now < this.NextTickTime) {
|
catch(Exception ex) {
|
||||||
continue;
|
if(!this.OnException(this,ex,stoppingToken)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this._isRunning = true;
|
//Schedule = new CronExpression(this.CronSchedule);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
var goOn = await this.Run(stoppingToken);
|
|
||||||
var comResult = this.OnCompleted(this,stoppingToken);
|
|
||||||
if(!goOn || !comResult) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception ex) {
|
|
||||||
if(!this.OnException(this,ex,stoppingToken)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SetNextTick();
|
|
||||||
this._isRunning = false;
|
|
||||||
}
|
}
|
||||||
this.OnStop(this,stoppingToken);
|
finally {
|
||||||
}
|
this.OnStop(this,stoppingToken);
|
||||||
|
}
|
||||||
private void SetNextTick(string? cronSchedule = null) {
|
|
||||||
var s = cronSchedule == null ? this.Schedule : new CronExpression(cronSchedule);
|
|
||||||
this.NextTickTime = s.GetNextOccurrence(DateTime.Now);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 释放对象
|
|
||||||
/// </summary>
|
|
||||||
public override void Dispose() {
|
|
||||||
this._timer?.Dispose();
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
base.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user