目录
项目场景
可以指定具体时间对某些任务的预约,定时执行
APScheduler
安装
使用pip命令安装:
pip install apscheduler
下载速度慢或者超时:
简介
APScheduler(Advanced Python Scheduler)是一个轻量级的Python定时任务调度框架(Python库)。
APScheduler有三个内置的调度系统,其中包括:
- cron式调度(可选开始/结束时间)
- 基于间隔的执行(以偶数间隔运行作业,也可以选择开始/结束时间)
- 一次性延迟执行任务(在指定的日期/时间内运行作业一次)
APScheduler组件
APScheduler共有4种组件,分别是:
- 触发器(trigger),触发器中包含调度逻辑,每个作业都有自己的触发器来决定下次运行时间。除了它们自己初始配置以外,触发器完全是无状态的。
- 作业存储器(job store),存储被调度的作业,默认的作业存储器只是简单地把作业保存在内存中,其他的作业存储器则是将作业保存在数据库中,当作业被保存在一个持久化的作业存储器中的时候,该作业的数据会被序列化,并在加载时被反序列化,需要说明的是,作业存储器不能共享调度器。
- 执行器(executor),处理作业的运行,通常通过在作业中提交指定的可调用对象到一个线程或者进程池来进行,当作业完成时,执行器会将通知调度器。
- 调度器(scheduler),配置作业存储器和执行器可以在调度器中完成。例如添加、修改、移除作业,根据不同的应用场景,可以选择不同的调度器,可选的将在下一小节展示。
触发器
当你调度作业的时候,你需要为这个作业选择一个触发器,用来描述这个作业何时被触发,APScheduler有三种内置的触发器类型:
- date 一次性指定日期
- interval 在某个时间范围内间隔多长时间执行一次
- cron 和Linux crontab格式兼容,最为强大
如何使用
当你需要调度任务的时候,你需要为这个任务选择一个触发器,用来描述该任务将在何时被触发,APScheduler有3中内置的触发器类型:
- 新建一个调度器(scheduler)
- 添加一个调度任务(job store)
- 运行调度任务
添加任务
有两种方式可以添加一个新的任务:
- add_job来添加任务
- 装饰器模式添加任务
使用
from apscheduler.schedulers.blocking import BlockingScheduler
class TaskScheduler:
def __init__(self):
self.scheduler = BlockingScheduler()
def schedule_task(self, func, schedule_type, **kwargs):
"""
创建并添加一个任务到调度程序中
:param func: 要执行的函数
:param schedule_type: 任务的调度类型,可以是 'interval', 'cron' 或 'date'
:param kwargs: 额外的调度选项,根据不同的调度类型有不同的选项,例如 run_date, start_date...
"""
self.scheduler.add_job(func, schedule_type, **kwargs)
def start(self):
"""
启动调度程序
"""
self.scheduler.start()
要执行的任务
# 你要执行的任务
def my_job(name, age):
print(f"执行任务,姓名:{name},年龄:{age}")
间隔执行
if __name__ == '__main__':
task_scheduler = TaskScheduler()
task_scheduler.schedule_task(my_job, 'interval', seconds=3, args=['胡某',18])
task_scheduler.start()
在上面这个例子中,每隔3秒(seconds)钟都会执行一次任务(可以根据自己的实际需求传入不同的时间单位),通过args参数向任务传递你所需要的参数。
task_scheduler.schedule_task(my_job, 'cron', day_of_week='*', hour=12, minute='00', second='00', args=['胡某',18])
每天中午的12点整点执行一次。
指定到具体时间执行
task_scheduler.schedule_task(my_job, 'date', run_date='2023-03-10 20:10:20',args=['胡某',18])
在这个例子中,任务将在2023年3月10日20:10:20执行,可以根据需要调整run_date
参数来指定不同的日期和时间。
FluentScheduler
安装
使用(Visual Studio)中的(程序包管理器控制台)Install-Package
Install-Package FluentScheduler
简介
FluentScheduler是一个简单的任务调度框架,定时任务管理器。
使用
public class ScheduledTask
{
private readonly Registry _registry;
private readonly Action _task;
public ScheduledTask(Action task)
{
_registry = new Registry();
_task = task;
}
/// <summary>
/// 间隔执行
/// </summary>
/// <param name="interval"></param>
/// <param name="timeUnit"></param>
public string RunEvery(int interval, TimeUnit timeUnit = TimeUnit.Seconds)
{
JobManager.Initialize(_registry);
return SetTaskUnit(interval, timeUnit);
}
/// <summary>
/// 指定任务的开始时间
/// </summary>
/// <param name="dateTime"></param>
/// <param name="action"></param>
public void RunOnceAt(DateTime dateTime, Action action = null)
{
Schedule _schedule = action == null ? _registry.Schedule(_task) : _registry.Schedule(action);
_schedule.ToRunOnceAt(dateTime);
JobManager.Initialize(_registry);
}
/// <summary>
/// 删除任务
/// </summary>
/// <param name="taskName">任务名</param>
/// <param name="isRemoveAll"></param>
public void RemoveTask(string taskName = "Task_001", bool isRemoveAll = false)
{
if (!isRemoveAll)
{
JobManager.RemoveJob(taskName);
}
else
JobManager.RemoveAllJobs();
}
/// <summary>
/// 根据时间单位设置对应的间隔时间任务
/// </summary>
/// <param name="interval"></param>
/// <param name="timeUnit"></param>
/// <param name="_taskName">任务名称</param>
/// <exception cref="ArgumentException"></exception>
private string SetTaskUnit(int interval, TimeUnit timeUnit,string _taskName = "Task_001")
{
Schedule _schedule = _registry.Schedule(_task).WithName(_taskName);
switch (timeUnit)
{
case TimeUnit.Seconds:_schedule.ToRunEvery(interval).Seconds(); return _taskName;
case TimeUnit.Minutes:_schedule.ToRunEvery(interval).Minutes(); return _taskName;
case TimeUnit.Hours: _schedule.ToRunEvery(interval).Hours(); return _taskName;
case TimeUnit.Days: _schedule.ToRunEvery(interval).Days(); return _taskName;
default:
throw new ArgumentException("无效的时间单位");
}
}
}
/// <summary>
/// 时间单位枚举
/// </summary>
public enum TimeUnit
{
Seconds,
Minutes,
Hours,
Days
}
间隔执行
ScheduledTask scheduledTask = new ScheduledTask(() =>
{
Console.WriteLine("666");
});
string _tName = scheduledTask.RunEvery(3, TimeUnit.Seconds);
这里的任务会每3秒执行一次(根据自己的实际需求来传入不同的时间单位,这里指定任务的间隔时间单位为秒),返回一个string类型的值,用来表示任务的别名。
指定到具体时间执行
DateTime dateTime = new DateTime(2023, 3, 10, 11, 46, 25);
scheduledTask.RunOnceAt(dateTime, new Action(() => { Console.WriteLine("999"); }));
接收一个datetime类型的参数,指定任务的开始时间为2023年3月10日11点46分25秒。
注意:如果指定时间早于当前时间,这个(预约)任务会立即执行。
官方文档:
User guide — APScheduler 3.9.1 documentation
apscheduler/userguide.rst at 3.x · agronholm/apscheduler (github.com)