周期性后台任务-同步版本

所有周期性后台任务需要实现 以下任意一个 抽象类:

  • BackgroundTask
  • AsyncBackgroundTask



BackgroundTask

BackgroundTask 是一个基类,当我们在项目中实现它的子类时,就能实现【后台周期性任务】,
AsyncBackgroundTask 是对应的异步版本。

它的主要公开成员如下:

/// <summary>
/// 表示一个后台运行的任务,它的子类会在程序启动时自动创建并运行
/// </summary>
public abstract class BackgroundTask
{
	/// <summary>
	/// 是否需要在每次执行Execute方法时自动生成日志(OprLog + InvokeLog)
	/// </summary>
	protected bool EnableLog => true;
	
	/// <summary>
	/// 获取休眠秒数,用于描述“周期任务”的间隔时间,例如:每5秒执行一次
	/// 注意:同步版本不支持时间跨度太久的休眠间隔。
	/// </summary>
	public virtual int? SleepSeconds {
		get => null;
	}

	/// <summary>
	/// 获取一个Cron表达式,用于描述“周期任务”的间隔时间。
	/// 这里使用的是 Quartz 支持的 Cron 格式,在线工具:https://www.pppet.net/
	/// 注意:同步版本不支持时间跨度太久的休眠间隔。
	/// </summary>
	public virtual string CronValue {
		get => null;
	}

	/// <summary>
	/// 执行任务前的初始化。
	/// 说明:执行当前方法时框架不做异常处理,如果产生异常会导致进程崩溃。
	/// </summary>
	/// <returns>如果 return false, 表示初始化失败,将中止任务</returns>
	public virtual bool Init()


	/// <summary>
	/// 执行任务的主体过程。
	/// </summary>
	public abstract void Execute();

	/// <summary>
	/// 异常处理方法。
	/// 默认行为:如果启用日志就不做任何处理,否则输出到Console
	/// </summary>
	/// <param name="ex"></param>
	public virtual void OnError(Exception ex)
	
}



要求&说明

子类的实现要求:

  • 类型的可见性必须是 public
  • 必须指定执行间隔属性: SleepSeconds 或者 CronValue

补充说明:

  • 子类的实例由Nebula在启动时创建并调用(项目中不需要实例化)
  • 内部已包含异常处理,如果需要额外的日志请重写OnError方法



BackgroundTask, AsyncBackgroundTask 差异

  • AsyncBackgroundTask 是异步版本,使用线程池执行作业
  • BackgroundTask 使用单独线程(不使用线程池),任务的及时触发率会更好
  • 如果对任务的【及时触发】要求不高,建议使用 AsyncBackgroundTask

  • AsyncBackgroundTask 支持较长的作业执行间隔,例如:一个月一次
  • BackgroundTask 【不支持】较长的作业执行间隔,建议 仅用于 10 秒内的间隔任务



示例1 - 休眠N秒的定时任务

public class Task1 : BackgroundTask
{
    public override int? SleepSeconds => 90;

    public override void Execute()
    {
        Console2.Info("Task1,每隔 90 秒执行一次!");
		// do something....
    }
}



示例2 - 基于CronValue的定时任务

public class Task2 : BackgroundTask
{
    public override string CronValue => "0/10 * * * * ? *";

    public override void Execute()
    {
        Console2.Info("Task2,每隔 10 秒执行一次!");
		// do something....
    }
}