Aicrosoft.Scheduling 8.5.0

dotnet add package Aicrosoft.Scheduling --version 8.5.0                
NuGet\Install-Package Aicrosoft.Scheduling -Version 8.5.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Aicrosoft.Scheduling" Version="8.5.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Aicrosoft.Scheduling --version 8.5.0                
#r "nuget: Aicrosoft.Scheduling, 8.5.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Aicrosoft.Scheduling as a Cake Addin
#addin nuget:?package=Aicrosoft.Scheduling&version=8.5.0

// Install Aicrosoft.Scheduling as a Cake Tool
#tool nuget:?package=Aicrosoft.Scheduling&version=8.5.0                

Aicrosoft.Scheduling

简单的多功能可扩展的任务调度框架 A multifunctional and extensible task scheduling framework Keywords: superjobs,task,job,routine,schedule,startup,interval,cronexpression

TODO

  • 前置任务,某个任务的运行要依赖另一个任务的成功。
  • 如果一个任务是一直运行模式,可以以一Job来触发它的另一个Worker,这个是个可以改进的地方。

使用说明 How To Use

一个具体的Task两部分组成:

  • SomeJob : Job : 必须,它是该Job任务的配置信息,名称,运行时间,等。可以是硬编码,也可以是在Appsettings.json中的配置。
    • 最好把Job配置在json配置中,以避免Job在DI中增加内存的消耗。
  • SomeWorker : TimerWorker, ITransient :不须一一对应,但是要有给Job可用的。不同类型的Job,如果执行的任务是同一类型的,可以由同样的Worker来运行。

注册事项

  • 只有SomeWorker才要加上ITransient来实现自动注入。SemeJob里Job基类已经标志了ITransient。
  • 具体的工作负载都是在SomeWorker.ExecuteAsync(CancellationToken)中来完成的。请注意任务的取消,以便急时取消任务。

一个Job程序集的例子


using Aicrosoft.Scheduler;
using Microsoft.Extensions.DependencyInjection;

namespace Aicrosoft.Jobs;

/// <summary>
/// Job的配置:它是该Job任务的配置信息,名称,运行时间,等。可以在josn文件中配置
/// </summary>
public class AppInsightsTelemetryJob : Job
{
    public AppInsightsTelemetryJob()
    {
        Timeout = 5;
        Trigger = "10000";
        WorkerType = this.GetTypeFullNameOf<AppInsightsTelemetryWorker>();
    }
}

/// <summary>
/// Job的实际执行者
/// </summary>
/// <remarks>
/// 不须与Job一一对应。但是每个Job必须有一个Worker。不同类型的Job,如果执行的任务是同一类型的,可以由同样的Worker来运行。
/// </remarks>
public class AppInsightsTelemetryWorker(IServiceProvider serviceProvider) : TimerWorker(serviceProvider), ITransient
{
    public override TriggerStyle RequiredStyles => TriggerStyle.Startup;

    protected override async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        if (cancellationToken.IsCancellationRequested) return;
        //work load.
    }
}

/// <summary>
/// 每个程序集必须有这个AppSetup类,才会自动加入工作集。
/// </summary>
public class JobAppSetup : JobAppSetupBase
{
}


关于独立插件实现的程序集

单独独立插件式Job的程序集

  • 单独的程序集Job必须以 xxxJob来命名。
  • 每个Job程序集中可以有多个Job,可以有自已的配置文件(不要与其它的程序集里的配置文件名相同即可)。
  • 继承PluginSetupBase重写相关方法即可注册服务类或配置绑定。默认实现了以程序集命名的json配置。
  • 程序集Job 项目属性里要加上 <EnableDynamicLoading>true</EnableDynamicLoading> 以便将所有的包的dll都拷贝过去。
  • 在Build PostEvent里加上脚本: call "$(ProjectDir)..\SuperJobsAgent\plugins-build.bat" "$(ProjectName)" "$(TargetDir)" "$(AssemblyName)"

关于Woker的使用的注意事项

  • Job的Trigger一旦设定就不能再修改它的类型;
  • 绝大数多数情况下,不用直接继承Worker。除非该Worker是立即运行;
  • 通过Task.Delay方式运行的方法并没有Timer的调用更高效,所以当前框架使用的是Timer;
  • TimerWorker有很多Protected方法实现了相关事件的调用;
  • 示例项目 SuperJobsAgent.Console 引入Fody后开发中不能急时生成开发的内容,最好是仅在Release中使用。
  • 示例项目中的公有资源配置及配置的Job信息移除,采用Job程序集中独立配置文件获取(注意不同Job的配置文件不要同名)。
  • Aicrosoft.Scheduling中增加并行运行的worker数量限制。
    • 只针对interval。且Job的Priority不为Always。
    • ConcurrentWorkers 参数表示Interval的非Always同时运行的数量。
    • WeightRate 参数表示每个不同级别的Job运行相差的倍率。
    • ⇐0 不限制。 直接用superviserjob来配置 且有个extend的初始化。

SuperJobs Architecture Design

Architecture Design UML

关于UML上Class创建与依赖的关系说明

  1. Instances are mostly created through DI through their interfaces.
  2. The interface instantiated by DI does not draw the relationship
  3. WorkShop 消费 Worker, WorkerPoolFactory 创建Woker。

关于UML 图及设计说明

  1. Job仅仅是对某一个任务的描述(名称,调度,由哪个Worker来运行等);
  2. Woker是执行Job的任务负载者。
  3. Job由两种已定义的JobProvider创建,这两个JobProvider能通过硬编码和配置设定Job信息,然后能过JobFactory汇总出所有的可用Jobs;
  4. Woker由WokerPoolProvider提供,然后由WokerPoolFactory汇总所有可用的Woker。;

工作要求类型(Worker.RequiredStyles)

  • 该类型与Job的JobTrigger中的Style是有对应关系的;
  • 该属性是个Flag枚举值;
  • 只有Job的Trigger Style符合Worker的RequiredStyles才能调用;

Job的触发器

根据传入的Triger类型来生成触发器

  • Default 通过其它的Woker来触发的Job,当下面的类型未检测到时转视为该类型 (目前没用到)
  • Startup 大于0的延迟启动毫秒数,Int类型的数字 ex:1200 该Worker用完后将被完全释放;
  • Interval 间隔运行的Job,Timespan类型 ex:00:01:00 负载运行时间不被算在间隔时间内 完成后回收到池;
  • Schedulable Cron表达式触发的Job,CronExpresssion表达式 ex:0 0/7 * * * ? 完成后回收到池中;

CRON 表达式详解 简单任务CRON表达式的详解


CRON 有如下两种语法格式:

  • 秒 分 小时 日期 月份 星期 年
  • 秒 分 小时 日期 月份 星期

每个域允许的值

允许的数值 允许的特殊字符 备注
0~59 - * / -
0~59 - * / -
小时 0~23 - * / -
日期 1~31 - * ? / L W C -
月份 1~12 或 JAN-DEC - * / -
星期 1~7 或 SUN-SAT - * ? / L C # 1 表示星期天,2 表示星期一,依次类推
年(可选) 留空,1970~2099 , - * / 自动生成,工具不显示该值

特殊字符的含义

字符 含义 示例
* 表示匹配域的任意值 在分这个域使用 *,即表示每分钟都会触发事件。
? 表示匹配域的任意值,但只能用在日期和星期两个域,因为这两个域会相互影响。 要在每月的 20 号触发调度,不管每个月的 20 号是星期几,则只能使用如下写法: 13 13 15 20 * ?。其中,因为日期域已经指定了 20 号,最后一位星期域只能用 ?,不能使用 *。如果最后一位使用 *,则表示不管星期几都会触发,与日期域的 20 号相斥,此时表达式不正确。
- 表示起止范围 在分这个域使用 5-20,表示从 5 分到 20 分钟每分钟触发一次。
/ 表示起始时间开始触发,然后每隔固定时间触发一次 在分这个域使用 5/20,表示在第 5 分钟触发一次,之后每 20 分钟触发一次,即 5、 25、 45 等分别触发一次。
, 表示列出枚举值 在分这个域使用 5,20,则意味着在 5 和 20 分每分钟触发一次。
L 表示最后,只能出现在日和星期两个域 在星期这个域使用 5L,意味着在最后的一个星期四触发。
W 表示有效工作日(周一到周五),只能出现在日这个域,系统将在离指定日期最近的有效工作日触发事件。 在日这个域使用 5W,如果 5 号是星期六,则将在最近的工作日星期五,即 4 号触发。如果 5 号是星期天,则在 6 号(周一)触发;如果 5 号为工作日,则就在 5 号触发。另外,W 的最近寻找不会跨过月份。
LW 这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
# 表示每个月第几个星期几,只能出现在星期这个域 在星期这个域使用 4#2,表示某月的第二个星期三,4 表示星期三,2 表示第二个。

示例

  • */5 * * * * ?:每隔 5 秒执行一次
  • 0 */1 * * * ?:每隔 1 分钟执行一次
  • 0 0 2 1 * ?:每月 1 日的凌晨 2 点执行一次
  • 0 15 10 ? * MON-FRI:周一到周五每天上午 10:15 执行作业
  • 0 15 10 ? 6L 2002-2006:2002 年至 2006 年的每个月的最后一个星期五上午 10:15 执行作业
  • 0 0 23 * * ?:每天 23 点执行一次
  • 0 0 1 * * ?:每天凌晨 1 点执行一次
  • 0 0 1 1 * ?:每月 1 日凌晨 1 点执行一次
  • 0 0 23 L * ?:每月最后一天 23 点执行一次
  • 0 0 1 ? * L:每周星期天凌晨 1 点执行一次
  • 0 26,29,33 * * * ?:在 26 分、29 分、33 分执行一次
  • 0 0 0,13,18,21 * * ?:每天的 0 点、13 点、18 点、21 点都执行一次
  • 0 0 10,14,16 * * ?:每天上午 10 点,下午 2 点,4 点执行一次
  • 0 0/30 9-17 * * ?:朝九晚五工作时间内每半小时执行一次
  • 0 0 12 ? * WED:每个星期三中午 12 点执行一次
  • 0 0 12 * * ?:每天中午 12 点触发
  • 0 15 10 ? * *:每天上午 10:15 触发
  • 0 15 10 * * ?:每天上午 10:15 触发
  • 0 15 10 * * ? *:每天上午 10:15 触发
  • 0 15 10 * * ? 2005:2005 年的每天上午 10:15 触发
  • 0 * 14 * * ?:每天下午 2 点到 2:59 期间的每 1 分钟触发
  • 0 0/5 14 * * ?:每天下午 2 点到 2:55 期间的每 5 分钟触发
  • 0 0/5 14,18 * * ?:每天下午 2 点到 2:55 期间和下午 6 点到 6:55 期间的每 5 分钟触发
  • 0 0-5 14 * * ?:每天下午 2 点到 2:05 期间的每 1 分钟触发
  • 0 10,44 14 ? 3 WED:每年三月的星期三的下午 2:10 和 2:44 触发
  • 0 15 10 ? * MON-FRI:周一至周五的上午 10:15 触发
  • 0 15 10 15 * ?:每月 15 日上午 10:15 触发
  • 0 15 10 L * ?:每月最后一日的上午 10:15 触发
  • 0 15 10 ? * 6L:每月的最后一个星期五上午 10:15 触发
  • 0 15 10 ? * 6L 2002-2005:2002 年至 2005 年的每月的最后一个星期五上午 10:15 触发
  • 0 15 10 ? * 6#3:每月的第三个星期五上午 10:15 触发

请注意,Markdown 格式不支持直接显示图片,因此原网页中的图片链接被保留为原样。如果需要在 Markdown 文档中显示图片,您可能需要将图片下载并上传到支持图片的 Markdown 编辑器或服务中,或者使用相应的 Markdown 图片语法。

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Aicrosoft.Scheduling:

Package Downloads
SuperJobs.Core

Extensions of Aicrosoft Ltd.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
8.5.0 87 10/12/2024
8.3.0 91 9/10/2024
8.2.0 97 8/7/2024
6.4.0 339 11/20/2023
6.3.2 143 11/1/2023
6.2.1 152 8/25/2023
6.1.7 168 7/25/2023
6.1.6 148 5/17/2023
6.1.5 235 3/13/2023
6.1.4 242 3/11/2023
6.1.3 260 2/21/2023