You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.1 KiB
7.1 KiB
任务执行调度 — 当前实现记录
记录时间:2026-06-13 状态:包材入库 (category=1, type=1) 任务驱动并行执行已跑通
一、整体架构
UI (SystemMonitorView)
├─ [▶ 启动] / [■ 停止] 包材入库调度
└─ SystemMonitorViewModel
└─ MaterialInStoreExecutor (Singleton)
Sln.Wcs.Strategy / MaterialInStoreExecutor
├─ 轮询待执行任务 (每 5 秒)
├─ 多任务并行 (Thread,最多 10 个)
├─ 单任务内串行 (逐条 detail)
└─ 设备下发 (AGV/提升机/输送线)
Sln.Wcs.Business / TaskCreateService
└─ 拓扑路由 → 自动生成 LiveTaskQueue + List<LiveTaskDetail>
二、任务创建
输入
| 参数 | 说明 | 示例 |
|---|---|---|
| startBuilding | 起始楼栋 | 13 |
| startFloor | 起始楼层 | 1 |
| startLocation | 起始位置号 | 101 |
| endBuilding | 目标楼栋 | 15 |
| endFloor | 目标楼层 | 3 |
| endLocation | 目标位置号 | 102 |
| taskType | 1入库 / 2出库 | 1 |
| taskCategory | 1包材 / 2成品 / 3托盘 | 1 |
| palletBarcode | 托盘条码 | PALLET001 |
| materialCode | 物料编码 | M001 |
输出
LiveTaskQueue
├─ taskCode: 自动生成 (yyyyMMddHHmmss + 随机数)
├─ taskType, taskCategory
├─ startPoint, endPoint: 自动拼接为 {building}#_L{floor}_{location}
├─ taskStatus: 1 (待执行)
├─ taskSteps: 明细数量
└─ taskDetails: List<LiveTaskDetail>
拓扑规则
- 所有楼栋 13# / 14# / 15# 均为 1~5F
- 每栋楼有 1 台提升机,可直达任意楼层(全连接)
- 跨栋仅 2F 连通:
- (13,2) ↔ (14,2):廊桥交接,两段 AGV(13# AGV → BRIDGE_13_14,14# AGV 从 BRIDGE_13_14 接走)
- (14,2) ↔ (15,2):14# AGV 可驶入 15#,不生成过渡段
示例:13栋1楼101 → 15栋3楼102
路由节点: (13,1) → (13,2) → (14,2) → (15,2) → (15,3)
Detail 1: AGV 13#_L1_101 → 13#_L1_HOIST
Detail 2: 提升机 13#_L1_HOIST → 13#_L2_HOIST
Detail 3: AGV 13#_L2_HOIST → BRIDGE_13_14 (13# AGV)
Detail 4: AGV BRIDGE_13_14 → 15#_L2_HOIST (14# AGV 直达)
Detail 5: 提升机 15#_L2_HOIST → 15#_L3_HOIST
Detail 6: AGV 15#_L3_HOIST → 15#_L3_102
三、任务执行
执行器:MaterialInStoreExecutor
位置:Sln.Wcs.Strategy/MaterialInStoreExecutor.cs
查询条件:
taskType == 1 && taskCategory == 1 && taskStatus == 1
轮询间隔:5 秒
主循环
Start()
└─ Task.Run → RunLoopAsync
└─ while (!cancelled):
ExecuteAsync() ← 阻塞等待所有任务线程完成
await Task.Delay(5000)
并行策略
ExecuteAsync:
查询所有待执行任务
→ foreach task → new Thread:
TaskSemaphore.Wait() ← 最多 10 线程
ProcessOneAsync(task).GetAwaiter().GetResult()
TaskSemaphore.Release()
→ Thread.Join() 等待全部完成
单任务处理
ProcessOneAsync(task):
🔒 lock → taskStatus = 2, Update(task)
foreach detail (按 objId 排序):
if detail 已完成 → continue
🔒 lock → detailStatus = 2, Update(detail)
🔓
下发设备 (根据 deviceType):
1 → DispatchAgvAsync (10s 模拟延迟)
2 → DispatchHoistAsync (20s 模拟延迟,按楼栋限 2 并发)
0 → DispatchConveyorAsync
🔒 lock → detailStatus = 3, Update(detail)
🔓
🔒 lock → taskStatus = 3, Update(task)
并发控制
| 控制点 | 机制 | 值 |
|---|---|---|
| 任务级并发 | SemaphoreSlim |
最多 10 个 |
| 提升机并发 | ConcurrentDictionary<int, SemaphoreSlim> |
每栋楼 2 台 |
| AGV 并发 | 不限 | — |
| DB 写入 | lock (DbWriteLock) 串行化 |
— |
| 启停状态 | lock (_lock) + volatile bool |
— |
线程安全
- 启停:
lock (_lock)保护_cts/_isRunning - DB 写入:
lock (DbWriteLock)保护 SqlSugar Update(Context 为单例,多线程写入冲突) - 提升机信号量:
ConcurrentDictionary线程安全 - 任务信号量:
SemaphoreSlim本身线程安全 - 延迟模拟:
await Task.Delay在锁外,多任务并行不受影响
四、仓储线程安全
位置:Sln.Wcs.Repository/Repository.cs
public Repository(ISqlSugarClient db)
{
itenant = db.AsTenant();
Context = (SqlSugarClient)db; // 直接用 SqlSugarScope,内部管理连接池
}
SqlSugarScope 注册为 Singleton,通过 [Tenant] 特性自动路由数据库。
五、设备下发(当前为模拟)
| 设备 | 方法 | 延迟 | 并发限制 |
|---|---|---|---|
| AGV | DispatchAgvAsync |
10 秒 | 无 |
| 提升机 | DispatchHoistAsync |
20 秒 | 每栋楼 2 台 |
| 输送线 | DispatchConveyorAsync |
无 | 无 |
后续对接:AGV → HikRoBotDispatchHub.ReciveTask,提升机 → HoistDispatchHub.TaskDispatch
六、UI 控制
系统监控页面 — 顶部卡片:
┌──────────────────────────────────────────────┐
│ ● 包材入库调度 运行中 [▶ 启动] [■ 停止] │
└──────────────────────────────────────────────┘
按钮绑定:
- 启动 →
MaterialInStoreExecutor.Start() - 停止 →
MaterialInStoreExecutor.Stop() - 状态指示灯:绿色 = 运行中,红色 = 已停止
七、DI 注册
App.axaml.cs:
// Assembly 扫描
Assembly.LoadFrom("Sln.Wcs.Strategy.dll")
// Singleton 注册
services.AddSingleton<MaterialInStoreExecutor>();
依赖关系:
MaterialInStoreExecutor (Singleton)
├─ SerilogHelper (Singleton)
├─ ILiveTaskQueueService (Transient, 来自 Scrutor 扫描)
└─ ILiveTaskDetailService (Transient, 来自 Scrutor 扫描)
八、关键文件
| 文件 | 说明 |
|---|---|
Sln.Wcs.Business/TaskCreateService.cs |
拓扑路由 + 任务创建 |
Sln.Wcs.Strategy/MaterialInStoreExecutor.cs |
包材入库执行器 |
Sln.Wcs.Repository/Repository.cs |
仓储基类(线程安全改造) |
Sln.Wcs.UI/ViewModels/SystemMonitorViewModel.cs |
系统监控 VM(启停控制) |
Sln.Wcs.UI/Views/SystemMonitorView.axaml |
系统监控页面 |
Sln.Wcs.UI/App.axaml.cs |
DI 注册 |
接驳位驱动调度方案.md |
调度方案设计文档 |
九、待优化项
- 真实设备对接:替换
DispatchAgvAsync/DispatchHoistAsync中的模拟延迟为实际 API 调用 - 扩展其他类型:成品入库/出库、托盘入库/出库等(参考 MaterialInStoreExecutor 模板)
- DB 写入优化:去掉
lock (DbWriteLock),从根本上解决 SqlSugar 多线程写入问题(可能需要连接串配置Max Pool Size或改造仓储层) - 任务优先级:当前 FIFO,可按优先级排序
- 异常恢复:任务中途停止后重新启动的状态恢复
- 手动触发:UI 上支持手动输入接驳位 + RFID 触发单条明细执行