using System;
using System.Threading;
using System.Threading.Tasks;
namespace OSS.Tools.TimerJob
{
///
/// 定时器基础类
///
public class TimerTriggerJob :BaseJobExecutor, IDisposable
{
private Timer _timer;
private readonly TimeSpan _dueTime;
private readonly TimeSpan _periodTime;
private CancellationToken _cancellationToken=CancellationToken.None;
#region 构造函数
///
/// 工作执行者
///
public IJobExecutor JobExcutor { get; }
///
/// 构造函数
///
/// 触发器名称
/// 到期开始执行时间
/// 间隔时间
/// 任务执行者
protected TimerTriggerJob(string triggerJobName, TimeSpan dueTime, TimeSpan periodTime, IJobExecutor jobExcutor)
: base(triggerJobName)
{
_dueTime = dueTime;
_periodTime = periodTime;
JobExcutor = jobExcutor;
}
///
protected TimerTriggerJob(string triggerJobName, TimeSpan dueTime, TimeSpan periodTime, string executeJobName, Func startAction, Func stopAction)
: this(triggerJobName, dueTime, periodTime, new InternalExecutor(executeJobName, startAction, stopAction))
{
}
///
protected TimerTriggerJob(string triggerJobName, TimeSpan dueTime, TimeSpan periodTime, string executeJobName, Func startAction)
: this(triggerJobName, dueTime, periodTime, executeJobName, startAction, null)
{
}
#endregion
#region 扩展方法
///
/// 指定时分秒和当前的时间差
///
///
///
///
///
protected static TimeSpan PointTimeSpan(int hour, int minute, int second)
{
const int fullDaySeconds = 24 * 60 * 60;
var now = DateTime.Now;
var startSeconds = now.Hour * 60 * 60 + now.Minute * 60 + now.Second;
var endSeconds = (hour * 60 * 60 + minute * 60 + second * 60) % fullDaySeconds;//防止输入溢出一天的周期
var spanSeconds = endSeconds - startSeconds;
if (spanSeconds < 0)
spanSeconds += fullDaySeconds;
return TimeSpan.FromSeconds(spanSeconds);
}
#endregion
protected override Task OnStarted(CancellationToken cancellationToken)
{
return StartTimerTrigger(cancellationToken);
}
protected override Task OnStoped(CancellationToken cancellationToken)
{
return StopTimerTrigger(cancellationToken);
}
#region 基础方法
///
/// 配置并触发定时器
///
///
private Task StartTimerTrigger(CancellationToken cancellationToken)
{
if (cancellationToken != CancellationToken.None)
{
_cancellationToken = cancellationToken;
}
if (_timer == null)
_timer = new Timer(ExcuteJob, null, _dueTime, _periodTime);
else
_timer.Change(_dueTime, _periodTime);
return Task.CompletedTask;
}
///
/// 停止定时器
///
private Task StopTimerTrigger(CancellationToken cancellationToken)
{
_timer?.Change(Timeout.Infinite, Timeout.Infinite);
return JobExcutor.StopAsync(cancellationToken);
}
private void ExcuteJob(object obj)
{
JobExcutor?.StartAsync(_cancellationToken).Wait(_cancellationToken);
}
///
public void Dispose()
{
_timer?.Dispose();
}
#endregion
}
}