Hyz.FreeScheduler 0.1.0

dotnet add package Hyz.FreeScheduler --version 0.1.0
                    
NuGet\Install-Package Hyz.FreeScheduler -Version 0.1.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="Hyz.FreeScheduler" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Hyz.FreeScheduler" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Hyz.FreeScheduler" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Hyz.FreeScheduler --version 0.1.0
                    
#r "nuget: Hyz.FreeScheduler, 0.1.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.
#:package Hyz.FreeScheduler@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Hyz.FreeScheduler&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Hyz.FreeScheduler&version=0.1.0
                    
Install as a Cake Tool

Hyz.FreeScheduler

基于开源 FreeScheduler 封装轻量化定时任务调度,支持集群任务、临时的延时任务和重复循环任务,可按秒、每天/每周/每月固定时间、自定义间隔执行。

特性

  • 支持 netstandard2.0;net8.0;net9.0;net10.0 多目标框架
  • 基于 FreeRedis 持久化,支持单节点、集群、哨兵、主从四种 Redis 连接模式
  • 自动扫描程序集中的 BaseJob 子类并注册
  • 支持 5 种任务间隔方式:按秒(SEC)、每天(RunOnDay)、每周(RunOnWeek)、每月(RunOnMonth)、自定义(Custom)
  • JobId/Expression 优先级规则:ScheduledJobAttribute > 类重写
  • CancellationToken 异步取消支持
  • 自动清理日志任务
  • Redis 缓存 TaskInterval 以枚举名称存储,可读性强

快速开始

1. 安装 NuGet 包

dotnet add package Hyz.FreeScheduler

2. 配置 appsettings.json

{
  "Redis": {
    "ConnectionString": "127.0.0.1:6379,password=xxx,poolsize=10,defaultDatabase=1"
  },
  "AutoClean": {
    "Enabled": true,
    "Expression": "0 0 0 1 * ?"
  }
}

3. 注册服务

using Hyz.FreeScheduler.Extensions;

builder.Services.AddHyzFreeSchedulerService(
    configureOptions: config =>
    {
        config.Redis = new RedisConfig()
        {
            ConnectionString = configuration.GetValue<string>("Redis:ConnectionString")!
        };
        config.AutoClean = new AutoCleanLogConfig()
        {
            Enabled = configuration.GetValue<bool>("AutoClean:Enabled"),
            Expression = configuration.GetValue<string?>("AutoClean:Expression") ?? "0 0 0 1 * ?"
        };
    },
    loggingBuilder: loggingBuilder => loggingBuilder.AddNLog(),
    assembly: typeof(Program).Assembly
);

var app = builder.Build();

// 停止时释放资源
app.Services.UseHyzDisposeFreeScheduler();

Redis 连接模式

支持四种 Redis 连接模式,通过 RedisConfig.Mode 指定,默认为 Single

Single - 单节点(默认)

{
  "Redis": {
    "ConnectionString": "127.0.0.1:6379,password=xxx,defaultDatabase=1"
  }
}

Cluster - 集群模式

只需提供部分主节点地址,客户端自动发现全部节点。

{
  "Redis": {
    "Mode": "Cluster",
    "Hosts": [
      "192.168.0.2:7001",
      "192.168.0.2:7002",
      "192.168.0.2:7003"
    ]
  }
}

Sentinel - 哨兵模式

ConnectionString 提供连接参数(如 password),MasterName 为哨兵监控的 master 名称,Hosts 为哨兵节点地址(默认端口 26379)。

{
  "Redis": {
    "Mode": "Sentinel",
    "ConnectionString": "password=xxx,defaultDatabase=1",
    "MasterName": "mymaster",
    "Hosts": [
      "192.168.1.10:26379",
      "192.168.1.11:26379",
      "192.168.1.12:26379"
    ],
    "ReadWriteSeparate": true
  }
}
参数 说明
MasterName 哨兵配置中的 master 名称
Hosts 哨兵节点地址列表
ReadWriteSeparate true=读走 slave/写走 master,false=读写都走 master

MasterSlave - 主从模式

ConnectionString 为主节点(写),Slaves 为从节点列表(读,随机选择)。

{
  "Redis": {
    "Mode": "MasterSlave",
    "ConnectionString": "127.0.0.1:6379,password=xxx,defaultDatabase=1",
    "Slaves": [
      "127.0.0.1:6380,password=xxx,defaultDatabase=1",
      "127.0.0.1:6381,password=xxx,defaultDatabase=1"
    ]
  }
}

代码配置示例

// 集群模式
config.Redis = new RedisConfig
{
    Mode = RedisMode.Cluster,
    Hosts = new[] { "192.168.0.2:7001", "192.168.0.2:7002", "192.168.0.2:7003" }
};

// 哨兵模式
config.Redis = new RedisConfig
{
    Mode = RedisMode.Sentinel,
    ConnectionString = "password=xxx,defaultDatabase=1",
    MasterName = "mymaster",
    Hosts = new[] { "192.168.1.10:26379", "192.168.1.11:26379" },
    ReadWriteSeparate = true
};

// 主从模式
config.Redis = new RedisConfig
{
    Mode = RedisMode.MasterSlave,
    ConnectionString = "127.0.0.1:6379,password=xxx",
    Slaves = new[] { "127.0.0.1:6380,password=xxx", "127.0.0.1:6381,password=xxx" }
};

定义定时任务

继承 BaseJob 并使用 [ScheduledJob] 特性标记:

Custom(默认)- CRON 表达式

[ScheduledJob(nameof(TestJob), Expression = "0/5 * * * * ?")]
public class TestJob : BaseJob
{
    public override async Task ExecuteAsync(CancellationToken cancellationToken = default)
    {
        // TODO: 实现任务逻辑
        await Task.CompletedTask;
    }
}

SEC - 按秒触发

[ScheduledJob(nameof(IntervalJob), TaskInterval = TaskInterval.SEC, Expression = "10")]
public class IntervalJob : BaseJob
{
    public override async Task ExecuteAsync(CancellationToken cancellationToken = default)
    {
        await Task.CompletedTask;
    }
}

RunOnDay - 每天固定时间

[ScheduledJob(nameof(DailyJob), TaskInterval = TaskInterval.RunOnDay, Expression = "20:00:00")]
public class DailyJob : BaseJob
{
    public override async Task ExecuteAsync(CancellationToken cancellationToken = default)
    {
        await Task.CompletedTask;
    }
}

RunOnWeek - 每周固定时间

// 每周一 20:00:00 执行(格式: 周几:时:分:秒)
[ScheduledJob(nameof(WeeklyJob), TaskInterval = TaskInterval.RunOnWeek, Expression = "1:20:00:00")]
public class WeeklyJob : BaseJob
{
    public override async Task ExecuteAsync(CancellationToken cancellationToken = default)
    {
        await Task.CompletedTask;
    }
}

RunOnMonth - 每月固定时间

// 每月1日 20:00:00 执行(格式: 日:时:分:秒)
[ScheduledJob(nameof(MonthlyJob), TaskInterval = TaskInterval.RunOnMonth, Expression = "1:20:00:00")]
public class MonthlyJob : BaseJob
{
    public override async Task ExecuteAsync(CancellationToken cancellationToken = default)
    {
        await Task.CompletedTask;
    }
}

JobId / Expression 优先级规则

JobIdExpression 支持两种来源,优先级:特性 > 类重写

场景 JobId 来源 Expression 来源 说明
特性提供全部 ScheduledJobAttribute.JobId ScheduledJobAttribute.Expression 类无需重写
特性仅提供 JobId 特性 类重写 Expression = null 时回退到类属性
特性仅提供 Expression 类重写 特性 [ScheduledJob(Expression = "...")]
无特性 类重写 类重写 类必须同时提供两者
均未提供 - - 启动时跳过并警告
// 示例:特性提供 JobId,Expression 从类属性读取
[ScheduledJob("MyJob")]
public class MyJob : BaseJob
{
    public override string Expression => "0/10 * * * * ?";

    public override async Task ExecuteAsync(CancellationToken cancellationToken = default)
    {
        await Task.CompletedTask;
    }
}

TaskInterval 间隔类型

枚举值 方法 Expression 格式 说明
SEC AddTask "10""5,10,15" 按秒触发,支持每轮不同间隔
RunOnDay AddTaskRunOnDay "20:00:00" 每天固定时间
RunOnWeek AddTaskRunOnWeek "1:20:00:00" 周几:时:分:秒
RunOnMonth AddTaskRunOnMonth "1:20:00:00""-1:20:00:00" 日:时:分:秒,负数为倒数第N天
Custom AddTaskCustom CRON 表达式 默认方式,基于 Cronos 解析

Round 循环次数

// 执行 10 次后自动停止(默认 -1 永久循环)
[ScheduledJob("MyJob", TaskInterval = TaskInterval.SEC, Expression = "5", Round = 10)]

配置项

SchedulerConfig

属性 类型 默认值 说明
Redis RedisConfig - Redis 连接配置
SchedulerKey string "Jobs:Scheduler" Redis Hash 存储键名
InjectionScheduler bool false 是否注入 IScheduler 到 DI 容器
TimeZoneOffsetHours int? 8 时区偏移小时数
AutoClean AutoCleanLogConfig - 自动清理日志配置

RedisConfig

属性 类型 默认值 说明
ConnectionString string - 主节点连接字符串 / Sentinel 连接参数
Mode RedisMode Single 连接模式:Single/Cluster/Sentinel/MasterSlave
Hosts string[]? null 集群节点或哨兵节点地址列表
MasterName string? null 哨兵监控的 master 名称(仅 Sentinel)
ReadWriteSeparate bool false 读写分离(仅 Sentinel)
Slaves string[]? null 从节点地址列表(仅 MasterSlave)

AutoCleanLogConfig

属性 类型 默认值 说明
Enabled bool false 是否启用自动清理
Expression string "0 0 0 1 * ?" 清理任务 CRON 表达式
CleanBeforeMin int 1440 清理多少分钟前的日志(默认 24 小时)
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 118 6/25/2026
0.0.9 348 8/25/2025
0.0.8 514 8/25/2025 0.0.8 is deprecated.
0.0.7 518 8/25/2025 0.0.7 is deprecated.
0.0.6 203 8/20/2025
0.0.5 203 8/18/2025
0.0.4 212 8/12/2025
0.0.3 366 8/5/2025 0.0.3 is deprecated because it has critical bugs.
0.0.2 318 8/4/2025 0.0.2 is deprecated because it has critical bugs.
0.0.1 308 8/4/2025 0.0.1 is deprecated because it has critical bugs.