7.7 KiB
定时任务源代码参考
文件位置总览
后台服务相关
1. LabelPdfCacheBackgroundService.cs
路径: src/CONTROLLER/BackgroundServices/LabelPdfCacheBackgroundService.cs
作用: 定时任务的主服务类
关键内容:
ExecuteAsync()- 后台服务的主方法,每5分钟执行一次TaskIntervalMinutes = 5- 执行间隔设置- 依赖注入了
ILabelPdfCacheService
示例代码位置:
- 第18行: 执行间隔定义
- 第25-40行: 构造函数和依赖注入
- 第42-70行: ExecuteAsync主方法实现
2. BackgroundServiceManager.cs
路径: src/CONTROLLER/BackgroundServices/BackgroundServiceManager.cs
作用: 管理后台服务的暂停/恢复
关键内容:
PauseService()- 暂停服务ResumeService()- 恢复服务IsRunning()- 检查运行状态GetCancellationToken()- 获取取消令牌
业务逻辑相关
3. LabelPdfCacheService.cs
路径: src/BLL/Services/LabelPdfCacheService.cs
作用: PDF缓存的业务逻辑处理
关键方法:
-
ProcessPendingTasksAsync()(第235-290行)- 处理失效缓存
- 处理待处理任务
- 处理新订单(仅>=2026-05-10)
-
ProcessSingleCacheTaskAsync()(第291-350行)- 处理单个订单
- 获取PDF字节流
- 同步保存缓存
- 异步识别条码
-
RecognizeBarcodeAsync()(第450-550行)- 条码识别逻辑
- 支持一维码和二维码
-
GetCacheStatisticsAsync()(第580-620行)- 获取统计信息
4. LabelPdfCacheBackgroundService.cs 中的调用
关键代码位置: 第50-65行
var successCount = await cacheService.ProcessPendingTasksAsync();
数据访问相关
5. LabelPdfCacheRepository.cs
路径: src/DAL/Repositories/LabelPdfCacheRepository.cs
关键方法:
-
GetNewOrdersWithLabelsAsync() (第142-152行)
- 获取新订单(无时间限制)
- 用于 batch-parse 接口
-
GetNewOrdersWithLabelsForBackgroundTaskAsync() (第183-200行)
- 获取新订单(仅>=2026-05-10)
- 仅用于定时任务
- 关键代码位置: 第186行
var cutoffDate = new DateTime(2026, 5, 10, 0, 0, 0);
-
GetInvalidCachesAsync() (第53-65行)
- 获取失效缓存
-
GetPendingTasksAsync() (第67-85行)
- 获取待处理任务
接口/API相关
6. LabelController.cs
路径: src/CONTROLLER/Controllers/LabelController.cs
定时任务相关接口:
-
batch-parse (第2510-2640行)
- POST
/api/label/batch-parse - 支持4种模式: all, range, customer, single
- 不受时间限制
- POST
-
cache-statistics (第2652-2670行)
- GET
/api/label/cache-statistics - 获取缓存统计信息
- GET
-
background-service/pause (需要实现)
- POST
/api/label/background-service/pause - 暂停定时任务
- POST
-
background-service/resume (需要实现)
- POST
/api/label/background-service/resume - 恢复定时任务
- POST
-
background-service/status (需要实现)
- GET
/api/label/background-service/status - 查看定时任务状态
- GET
关键代码片段
定时任务执行流程
文件: LabelPdfCacheService.cs 第235-290行
public async Task<int> ProcessPendingTasksAsync(int maxRetryCount = 3, int batchSize = 100)
{
var successCount = 0;
try
{
// 第一步:处理失效的缓存
var invalidCaches = await _cacheRepository.GetInvalidCachesAsync(batchSize);
// 第二步:处理待处理的任务
var remainingBatchSize = batchSize - invalidCaches.Count;
var pendingTasks = await _cacheRepository.GetPendingTasksAsync(maxRetryCount, remainingBatchSize);
// 第三步:处理订单表中新的有标签订单(仅>=2026-05-10)
var newBatchSize = remainingBatchSize - pendingTasks.Count;
if (newBatchSize > 0)
{
// 使用专用方法获取新订单(受时间限制)
var newOrders = await _cacheRepository.GetNewOrdersWithLabelsForBackgroundTaskAsync(newBatchSize);
foreach (var waybillNumber in newOrders)
{
if (await ProcessSingleCacheTask(waybillNumber))
{
successCount++;
}
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in ProcessPendingTasksAsync");
}
return successCount;
}
定时任务新订单查询(受时间限制)
文件: LabelPdfCacheRepository.cs 第183-200行
public async Task<List<string>> GetNewOrdersWithLabelsForBackgroundTaskAsync(int limit)
{
var db = _provider.GetClient();
// 定义截断日期:仅处理2026-05-10之后的订单
var cutoffDate = new DateTime(2026, 5, 10, 0, 0, 0);
return await db.Queryable<LabelReplaceEntity>()
.Where(o => !string.IsNullOrEmpty(o.Label))
.Where(o => o.CreatedAt >= cutoffDate) // ⭐ 时间限制
.Where(o => !SqlFunc.Subqueryable<LabelPdfCache>()
.Where(c => c.NeutralWaybillNumber == o.NeutralWaybillNumber)
.Any())
.Select(o => o.NeutralWaybillNumber)
.Take(limit)
.ToListAsync();
}
通用新订单查询(无时间限制)
文件: LabelPdfCacheRepository.cs 第142-152行
public async Task<List<string>> GetNewOrdersWithLabelsAsync(int limit)
{
var db = _provider.GetClient();
return await db.Queryable<LabelReplaceEntity>()
.Where(o => !string.IsNullOrEmpty(o.Label))
// ⭐ 没有时间限制
.Where(o => !SqlFunc.Subqueryable<LabelPdfCache>()
.Where(c => c.NeutralWaybillNumber == o.NeutralWaybillNumber)
.Any())
.Select(o => o.NeutralWaybillNumber)
.Take(limit)
.ToListAsync();
}
配置参数修改位置
1. 执行间隔 (5分钟)
文件: LabelPdfCacheBackgroundService.cs 第18行
private const int TaskIntervalMinutes = 5;
改为: 所需的分钟数
2. 批处理大小 (100条)
文件: LabelPdfCacheService.cs ProcessPendingTasksAsync方法参数
public async Task<int> ProcessPendingTasksAsync(int maxRetryCount = 3, int batchSize = 100)
改为: 所需的批处理大小
3. 重试次数 (3次)
文件: LabelPdfCacheService.cs ProcessPendingTasksAsync方法参数
public async Task<int> ProcessPendingTasksAsync(int maxRetryCount = 3, int batchSize = 100)
改为: 所需的重试次数
4. 时间限制日期 (2026-05-10)
文件: LabelPdfCacheRepository.cs GetNewOrdersWithLabelsForBackgroundTaskAsync方法
var cutoffDate = new DateTime(2026, 5, 10, 0, 0, 0);
改为: 所需的日期
依赖关系
LabelPdfCacheBackgroundService
↓
└─→ ILabelPdfCacheService
↓
├─→ ILabelPdfCacheRepository
│ ↓
│ └─→ SqlSugar (数据库)
│
└─→ ILogger
调试技巧
打断点位置
- 定时任务执行:
LabelPdfCacheBackgroundService.ExecuteAsync() - 处理逻辑:
LabelPdfCacheService.ProcessPendingTasksAsync() - 单个订单处理:
LabelPdfCacheService.ProcessSingleCacheTaskAsync() - 查询新订单:
LabelPdfCacheRepository.GetNewOrdersWithLabelsForBackgroundTaskAsync()
查看日志
日志文件位置: logs/ 目录
关键日志关键字:
- "Label PDF Cache Background Service is starting"
- "Starting label PDF cache processing task"
- "Completed label PDF cache processing task"
- "Error occurred in label PDF cache background service"
最后更新: 2026-05-14