如果前面的各种设置无法满足你的要求,你可能需要的是计划任务。QWorker 支持 Linux 的 Cron 计划任务配置文件格式,可以直接调用 Plan 函数来传递格式字符串到程序中进行任务调度。
与普通的作业不同,计划的作业任务分辨率比较粗,与 Linux Cron 配置文件格式一样精确到分钟。
QWorker 支持的 Linux 的 Cron 格式说明:
分 时 日 月 周 命令
如果某一位置值为“*”,则代表忽略这一条件,只要其它条件符合就执行;
支持 n-n 格式的范围,如 3-6 代表从 3 到 6;
支持间隔设置,格式为/n,如/2;
同一位置的多个时间值之间可以用 “,” 直接分隔。
周后面的命令不支持换行,后面所有内容直接被当做命令保存下来,赋给 TQPlanMask.Content 成员。
下面是几个例子:
- 每分钟执行一次: * * * * *
- 每小时 5 分执行一次:5 * * * *
- 每个月 1 号 23:00 执行一次:0 23 1 * *
- 每周一晚上 23:00 执行一次:0 23 * * 1
- 每小时的 30-40 分钟,每隔两分钟执行一次:30-40/2 * * * *
- 每小时的 10 分和 35 分各执行一次: 10,35 * * * *
QDAC 对命令格式的检查进行了一些较宽容的处理,如下面的格式也认为是合适的值:
3 这是计划任务
上面创建的是每小时的3分执行的计划任务。也就是说,遇到无效的字符就认为是命令的开始。
现在看下QWorker 的 Plan 函数声明:
【Delphi】
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; 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;
【C++】
NativeInt __fastcall Plan(TQJobProc AProc, const Qtimetypes::TQPlanMask &APlan, void * AData, bool ARunInMainThread = false, TQJobDataFreeType AFreeType = (TQJobDataFreeType)(0x0))/* overload */; NativeInt __fastcall Plan(TQJobProc AProc, const System::UnicodeString APlan, void * AData, bool ARunInMainThread = false, TQJobDataFreeType AFreeType = (TQJobDataFreeType)(0x0))/* overload */; NativeInt __fastcall Plan(TQJobProcG AProc, const Qtimetypes::TQPlanMask &APlan, void * AData, bool ARunInMainThread = false, TQJobDataFreeType AFreeType = (TQJobDataFreeType)(0x0))/* overload */; NativeInt __fastcall Plan(TQJobProcG AProc, const System::UnicodeString APlan, void * AData, bool ARunInMainThread = false, TQJobDataFreeType AFreeType = (TQJobDataFreeType)(0x0))/* overload */; NativeInt __fastcall Plan(_di_TQJobProcA AProc, const Qtimetypes::TQPlanMask &APlan, void * AData, bool ARunInMainThread = false, TQJobDataFreeType AFreeType = (TQJobDataFreeType)(0x0))/* overload */; NativeInt __fastcall Plan(_di_TQJobProcA AProc, const System::UnicodeString APlan, void * AData, bool ARunInMainThread = false, TQJobDataFreeType AFreeType = (TQJobDataFreeType)(0x0))/* overload */;
其中的 APlan 参数可以是 TQPlanMask 或者是 Linux Cron 兼容的计划任务字符串,内部自动解析处理。至于其它参数和普通的 Post 作业完全一样,也不就再解释。
【Delphi】
Workers.Plan(DoPlanJob,TQPlanMask.Create('* * * * * 1 Minute Plan Job'),nil,true);
【C++】
Workers->Plan(DoPlanJob,TQPlanMask.Create(L"* * * * * 1 Minute Plan Job"),NULL,true);
和
【Delphi】
Workers.Plan(DoPlanJob,'* * * * * 1 Minute Plan Job',nil,true);
【C++】
Workers->Plan(DoPlanJob,"* * * * * 1 Minute Plan Job",NULL,true);
用到的 DoPlanJob 函数:
【Delphi】
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;
【C++】
void __fastcall TForm1::DoPlanJob(PQJob AJob); { PQJob APlan=PQJob(AJob.PlanJob); lblPlanStatic->Caption=L"计划任务已执行"+IntToStr(AJob.Runs+1)+L"次\r\n内容:'+APlan->ExtData->AsPlan->Plan->Content; }
效果是完全等价的两个调用,实际执行效果: