任务调度(Aegis.Jobs)
Aegis.Jobs 是 Aegis 的延迟任务与后台任务基础组件。它负责提供 AegisJob.Schedule(...) 调度入口、任务表达式序列化、任务执行器和基础后台服务。
组件概览
| 字段 | 说明 |
|---|---|
| 组件名称 | 任务调度 |
| 真实类库 | Aegis.Jobs |
| 组件定位 | 延迟任务调度基础组件 |
| 引入方式 | 安装 NuGet,并在 Component.deps.json 的 Services 中启用 Jobs |
| 组件声明 | Jobs |
| 核心能力 | AegisJob.Schedule(...)、任务表达式持久化、任务执行器、心跳服务 |
| 典型配套 | Aegis.Jobs.Postgres、Aegis.Jobs.SqlServer |
什么时候要用它
适合场景:
- 需要把一段逻辑延后执行
- 需要把服务方法包装成后台任务
- 需要在业务完成后异步执行通知、同步、补偿类逻辑
先记住它和存储扩展的关系
Aegis.Jobs 负责调度基础能力,但当前公开文档默认按“基础组件 + 存储扩展”的完整链路使用。
| 组合方式 | 适合什么场景 |
|---|---|
Aegis.Jobs + Aegis.Jobs.Postgres | 当前 3.x 的标准持久化方案,适合正式环境 |
Aegis.Jobs + Aegis.Jobs.SqlServer | 需要沿用 SQL Server 的项目,但当前按手动注册接入 |
如果你要一条默认靠谱的路径,直接走 Aegis.Jobs + Aegis.Jobs.Postgres。
最小可运行路径
第一步:在组件配置里启用 Jobs
{
"Components": {
"Services": [
"Jobs",
"Jobs.Postgres"
],
"Middlewares": []
}
}
这里只展示当前推荐的标准链路。
如果你需要 SQL Server 存储,请结合 SqlServer 任务存储扩展 页面一起接入。
第二步:准备 ServerSettings
{
"ServerSettings": {
"ServerId": "1"
}
}
ServerId 建议在每台服务实例上保持唯一。
第三步:直接调度任务
var jobId = AegisJob.Schedule(
() => Console.WriteLine("测试"),
TimeSpan.FromSeconds(5));
最常见的四种调度方式
调度当前上下文或静态方法
var jobId = AegisJob.Schedule(
() => ChangeUser(id, statusCode),
TimeSpan.FromSeconds(15));
调度异步静态方法或异步上下文方法
var jobId = AegisJob.Schedule(
() => PublishAsync(orderId),
TimeSpan.FromSeconds(10));
调度服务类实例方法
var jobId = AegisJob.Schedule<UserService>(
x => x.DelayQueueTest(DateTime.Now.Day),
TimeSpan.FromSeconds(30));
这种写法适合直接调度已经注册到 DI 的服务。
调度专门的 Job 类
var jobId = AegisJob.Schedule<TestJob>(
x => x.Test(2),
TimeSpan.FromSeconds(1));
如果任务逻辑比较长、会递归调度、或者你希望它和普通业务服务分开,建议单独建 Job 类。
怎么取消任务
var jobId = AegisJob.Schedule<TestJob>(
x => x.Test(2),
TimeSpan.FromMinutes(1));
var canceled = AegisJob.Cancel(jobId);
适合场景:
- 业务撤回后取消未执行任务
- 延迟通知在状态变化后需要作废
任务状态
| 状态 | 含义 |
|---|---|
Scheduled | 已写入存储,等待执行时间到达 |
Queued | 已进入执行队列 |
Processing | 正在执行 |
Succeeded | 执行成功 |
Failed | 执行失败 |
Canceled | 已取消 |
Aborted | 中断退出,等待后续恢复或处理 |
使用时要守住的几个约束
任务方法建议满足下面这些条件:
- 方法必须是
public - 异步方法返回值必须是
Task,不要用async void - 不要使用
ref、out - 不要传入委托或表达式参数
如果方法不满足这些约束,调度阶段就可能直接失败。
接入后怎么确认已经生效
可以用下面几种方式确认:
- 启动应用后没有
Jobs相关初始化异常 - 调用
AegisJob.Schedule(...)能返回任务编号 - 延迟时间到达后,目标方法被实际执行
常见问题
ServerId 要不要配
建议配,而且多实例部署时每台机器都要唯一。
这是任务节点识别和心跳管理的基础配置。
应该直接调度 Service,还是单独建 Job 类
两种都可以:
- 简单任务、已有服务方法,直接调度服务类更省事
- 长任务、递归任务、批处理任务,单独建 Job 类更清晰