namespace OSS.Tools.TimerJob; /// /// 列表循环处理任务执行 /// 从 GetExecuteSource() 获取执行数据源,循环并通过 ExecuteItem() 执行个体任务,直到没有数据源返回 /// 如果执行时间过长,重复触发同一实例时 如果当前任务还在进行中,则不做任何处理 /// public abstract class BaseListJobExecutor : Internal_BaseExecutor, IJobExecutor { /// public string JobName { get; } private readonly bool _isExecuteOnce; /// /// 列表任务执行者 /// /// /// 是否只获取一次数据源 protected BaseListJobExecutor(string jobName, bool getSourceOnce) //: base(jobName) { JobName = jobName; _isExecuteOnce = getSourceOnce; } /// /// 列表任务执行者 /// protected BaseListJobExecutor(string jobName) : this(jobName, false) { } #region 任务接口实现 internal override async Task InternalStartJob(CancellationToken cancellationToken) { var pageIndex = 0; IList list; // 结清实体list await OnBegin(cancellationToken); while (IsStillRunning(cancellationToken) && (list = await GetExecuteSource(pageIndex++))?.Count > 0) { for (var i = 0; IsStillRunning(cancellationToken) && i < list?.Count; i++) { await ExecuteItem(list[i], i); } if (_isExecuteOnce) { break; } } await OnEnd(cancellationToken); } private bool IsStillRunning(CancellationToken cancellationToken) { return StatusFlag == StatusFlag.Running && !cancellationToken.IsCancellationRequested; } #endregion #region 扩展方法 /// /// 获取list数据源, 此方法会被循环调用 /// /// 获取数据源的页数索引,从0开始 /// protected abstract Task> GetExecuteSource(int pageIndex); /// /// 个体任务执行 /// /// 单个实体 /// 在数据源中的索引 protected abstract Task ExecuteItem(T item, int index); /// /// 此轮任务开始 /// protected virtual Task OnBegin(CancellationToken cancellationToken) { return Task.CompletedTask; } /// /// 此轮任务开始 /// protected virtual Task OnEnd(CancellationToken cancellationToken) { return Task.CompletedTask; } #endregion }