QWorker 更新 – 新增 Plan 函数添加个一个 Linux 样式的计划任务作业

【更新说明】

QWorker 新增了一个 Plan 函数来做计划任务作业的处理,与 At 和 Post 函数不同,Plan的计划任务掩码精度是精确到秒,而本次任务与下次任务之间的时间间隔并不是固定的,如每月1号执行的任务,牵涉到大小月间隔就不一样了。所以 QWorker 内部维护了一个独立的队列来处理此问题。

QWorker 使用 QTimeTypes 里的 TQPlanMask 来管理任务计划设置(它是一个结构/记录体)。

关于QWorker 支持的 Linux 的 Cron 格式说明:

秒 分 时 日 月 周 年 命令

如果某一位置值为“*”,则代表任意值,“?” 代表忽略这一条件,只要其它条件符合就执行;

日部分支持 “L” 操作符,代表月内倒数多少天,如 L-2 代表这个月末倒数两天前,如 7 月份有31天,倒数 0 天是 31 号,倒数 1 天是 30 号,倒数 2 天也就成了 29 号。

周部分支持 “L” 和 “W” 操作符,如 5L 代表月内最后一周的周四,而 “W” 代表是工作日。

支持 n-n 格式的范围,如 3-6 代表从 3 到 6;

支持间隔设置,格式为/n,如/2;

同一位置的多个时间值之间可以用 “,” 直接分隔。

周后面的命令不支持换行,后面所有内容直接被当做命令保存下来,赋给 TQPlanMask.Content 成员。

下面是几个例子:

  1. 每分钟执行一次:0 0 * * * * *
  2. 每小时 5 分执行一次:0 5 * * * * *
  3. 每个月 1 号 23:00 执行一次:0 0 23 1 * * *
  4. 每周一晚上 23:00 执行一次:0  0 23 * * 1 *
  5. 每小时的30-40,每隔两分钟执行一次:0 30-40/2 * * * * *
  6. 每小时的 10 分和 35 分各执行一次: 0 10,35 * * * * *

QDAC 对命令格式的检查进行了一些较宽容的处理,如下面的格式也认为是合适的值:

3 这是计划任务

上面创建的是每小时每分钟的第3秒执行的计划任务。也就是说,遇到无效的字符就认为是命令的开始。

现在看下QWorker 的 Plan 函数声明:

function Plan(AProc: TQJobProc; const APlan: TQPlanMask; AData: Pointer;ARunInMainThread: Boolean = False;AFreeType: TQJobDataFreeType = jdfFreeByUser): IntPtr; overload;
function Plan(AProc: TQJobProc; const APlan: QStringW; AData: Pointer;ARunInMainThread: Boolean = False;AFreeType: TQJobDataFreeType = jdfFreeByUser): IntPtr; overload;
function Plan(AProc: TQJobProcG; const APlan: TQPlanMask; AData: Pointer;ARunInMainThread: Boolean = False;AFreeType: TQJobDataFreeType = jdfFreeByUser): IntPtr; overload;
function Plan(AProc: TQJobProcG; const APlan: QStringW; AData: Pointer;ARunInMainThread: Boolean = False;AFreeType: TQJobDataFreeType = jdfFreeByUser): IntPtr; overload;
{$IFDEF UNICODE}
function Plan(AProc: TQJobProcA; const APlan: TQPlanMask; AData: Pointer;ARunInMainThread: Boolean = False;AFreeType: TQJobDataFreeType = jdfFreeByUser): IntPtr; overload;
function Plan(AProc: TQJobProcA; const APlan: QStringW; AData: Pointer;ARunInMainThread: Boolean = False;AFreeType: TQJobDataFreeType = jdfFreeByUser): IntPtr; overload;
{$ENDIF}

其中的 APlan 参数可以是 TQPlanMask 或者是 Linux Cron 兼容的计划任务字符串,内部自动解析处理。至于其它参数和普通的 Post 作业完全一样,也不就再解释。

Workers.Plan(DoPlanJob,TQPlanMask.Create('0 * * * * * 1 Minute Plan Job'),nil,true);

Workers.Plan(DoPlanJob,'0 * * * * * 1 Minute Plan Job',nil,true);

用到的 DoPlanJob 函数:

procedure TForm1.DoPlanJob(AJob: PQJob);
var
  APlan:PQJob;
begin
APlan:=AJob.PlanJob;
lblPlanStatic.Caption:='计划任务已执行'+IntToStr(AJob.Runs+1)+'次'#13#10+'内容:'+APlan.ExtData.AsPlan.Plan.Content;
end;

效果是完全等价的两个调用,实际执行效果:

QWorkerPlan

分享到: