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 } }