using System; using System.Threading; using System.Threading.Tasks; namespace OSS.Tools.TimerJob { /// /// 定时器基础类 /// public class BaseTimerTrigger : IDisposable { private Timer _timer; private readonly TimeSpan _dueTime; private readonly TimeSpan _periodTime; private readonly IJobExecutor _jobExcutor; private CancellationToken _cancellationToken=CancellationToken.None; /// /// 构造函数 /// /// 到期开始执行时间 /// 间隔时间 /// 任务执行者 protected BaseTimerTrigger(TimeSpan dueTime, TimeSpan periodTime, IJobExecutor jobExcutor) { _dueTime = dueTime; _periodTime = periodTime; _jobExcutor = jobExcutor; } /// protected BaseTimerTrigger(TimeSpan dueTime, TimeSpan periodTime,string jobName, Func startAction, Func stopAction) { _dueTime = dueTime; _periodTime = periodTime; _jobExcutor = new InternalExecutor(jobName,startAction, stopAction); } /// protected BaseTimerTrigger(TimeSpan dueTime, TimeSpan periodTime, string jobName, Func startAction) { _dueTime = dueTime; _periodTime = periodTime; _jobExcutor = new InternalExecutor(jobName, startAction, null); } #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 #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 void StopTimerTrigger() { _timer?.Change(Timeout.Infinite, Timeout.Infinite); } /// public void Dispose() { _timer?.Dispose(); } #endregion /// /// 系统级任务执行启动 /// /// /// public virtual Task StartAsync(CancellationToken cancellationToken) { return StartTimerTrigger(cancellationToken); } /// /// 系统级任务执行关闭 /// /// /// public virtual async Task StopAsync(CancellationToken cancellationToken) { await _jobExcutor.StopJob(cancellationToken); StopTimerTrigger(); } private void ExcuteJob(object obj) { _jobExcutor?.StartJob(_cancellationToken).Wait(_cancellationToken); } } }