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
}