目前架构已经完成了基础拆分,但仍属于“渐进迁移阶段”,部分服务只是代理层,核心业务仍在 `StationControlViewModel` 中
2026/9/7 20:52:40 网站建设 项目流程

还有优化空间。目前架构已经完成了基础拆分,但仍属于“渐进迁移阶段”,部分服务只是代理层,核心业务仍在StationControlViewModel中。

一、当前最需要优化的问题

  1. StationAutomationService 目前仍是代理服务

StationAutomationService已经提供了统一入口,但实际执行仍通过:

HandleEapStartLotAsync HandleEapSOTAsync HandleEapUnloadAsync

回调到StationControlViewModel

因此目前只是“调用路径解耦”,并没有完全实现自动化业务迁移。后续应该将以下核心逻辑迁移到独立服务:

  • StationAutomationService
    • 只负责自动化协议业务
  • StationLifecycleService
    • 初始化、停止、复位、结批
  • StationMaterialService
    • 上料、搬运、吹扫、下料
  • StationTestService
    • 预测试、正式测试、结果保存
  • StationUiAdapter
    • 只负责修改界面属性和弹窗

最终StationControlViewModel只保留按钮命令、属性绑定和服务调用。


  1. MainWindow 仍然知道 ViewModel

目前MainWindow.xaml.cs仍然通过主页查找:

homeView.ViewModel.Stations.FirstOrDefault(...)

然后取得工站 ViewModel。

这会导致:

  • 通信层依赖 WPF 页面结构
  • 工站集合必须已经创建
  • 页面关闭或切换时存在空引用风险
  • 后续增加后台模式、无界面运行模式比较困难

建议增加独立的:

StationServiceRegistry

由它维护:

StationId -> StationApplicationService

通信层只根据站号查找业务服务,不再查找 ViewModel。


  1. 自动化业务仍然大量依赖 Dispatcher

当前自动化命令通过:

Application.Current.Dispatcher.InvokeAsync(...)

进入 UI 线程。

这会有两个问题:

  • PLC 同步读写可能阻塞 UI
  • 自动化网络请求可能拖慢界面响应
  • 多个工站同时开批时,所有业务都经过 UI Dispatcher 排队
  • 后台线程异常可能无法正常返回协议层

建议明确区分:

后台业务线程: PLC、主控板、负载板、文件、数据库、协议等待 UI线程: 按钮状态、进度、灯态、弹窗、界面属性

业务服务不能整体运行在 UI 线程,只能在需要更新界面时调用StationUiAdapter


  1. 硬件资源仍缺少统一互斥

目前工站命令邮箱可以保证:

StartLot SOT EndLot Unload Reset

之间的顺序。

但以下业务仍可能来自不同线程:

  • 自动化命令
  • 自动流水线 Worker
  • PLC 实时采集
  • 手动操作
  • 停止流程
  • 复位流程
  • 下料流程

如果它们同时操作同一个 PLC 或主控板,仍然可能出现:

  • 同时发送主控板指令
  • 测试过程中被复位
  • 下料过程中又写入搬运命令
  • PLC 通讯响应错配
  • 同一 TCP 连接被多个流程抢占

建议增加工站级资源锁:

MainBoardCommandGate PlcCommandGate LoadUnitCommandGate RfidCommandGate WorkflowGate

普通读取可以并发,但动作类指令必须串行。


  1. SOT 预占用还没有完整实现幂等

当前AutomationSotReservation已经解决:

  • 必须先SOTReadyReq
  • 重复SOTReadyReq
  • SOTReadySOT状态转换
  • 复位和解锁清理占用

但它还不能处理完整的网络重试场景。

例如:

SOTReq SN=1001 第一次已经成功 EAP没有收到回复 EAP再次发送相同的 SOTReq SN=1001

当前可能返回:

当前预占用正在处理SOTReq

或者重复进入业务。

工业级做法应增加请求幂等缓存:

Station + Command + SN + RequestPayloadHash

保存:

请求状态 请求时间 请求结果 响应报文

相同请求重复到达时直接返回原响应,不重复搬运、不重复测试、不重复写 PLC。


  1. AutomationBusinessHandler 职责仍然过重

目前AutomationBusinessHandler同时承担:

  • 报文解析
  • 参数校验
  • 配方查找
  • 协议日志
  • 回包组装
  • 工站查找
  • 业务执行器调用
  • 错误处理
  • 请求 SN 管理

建议拆成:

AutomationTcpProtocolAdapter 负责 JSON/TCP 收发和 JSON 字段解析 AutomationCommandRouter 负责 Command 路由 AutomationRequestValidator 负责参数、配方和批次校验 StationAutomationService 负责工站自动化业务 AutomationResponseFactory 负责生成响应报文 AutomationRequestIdStore 负责请求幂等和重复报文处理

这样不同客户增加命令时,不需要继续修改一个巨大的 Handler。


  1. 真正 EAP 和 Automation 仍需进一步隔离

当前 JSON/TCP 自动化和 SECS/GEM 已经有区别,但部分代码仍然共用:

  • AutomationBusinessHandler
  • AutomationBusinessGateway
  • StationControlViewModel
  • 部分HandleEap...命名

建议最终结构如下:

Automation/ AutomationTcpServer AutomationProtocolAdapter AutomationCommandRouter StationAutomationService Eap/ SecsGemService EapEventService EapCommandMapper StationEapService

二者可以共用:

StationLifecycleService StationMaterialService StationTestService StationRuntime

但不应共用协议语义。

例如:

Automation SOTReq

表示外部自动化已经放料并提供 DUTSN。

而:

SECS/GEM AcceptItem

表示 Host 接受本机扫码结果。

二者不能直接互相替代。


二、当前状态机仍需要升级

当前状态机已经能够记录非法跳转,但如果所有业务仍然由 ViewModel 修改状态,状态机无法成为唯一状态来源。

建议顺序:

  1. 生命周期逻辑迁移完成
  2. 测试逻辑迁移完成
  3. 自动化逻辑迁移完成
  4. EAP 逻辑迁移完成
  5. 所有状态修改统一进入状态机
  6. 最后把“记录非法跳转”改为“拒绝非法跳转”

例如:

Idle -> StartingBatch StartingBatch -> BatchReady BatchReady -> Loading Loading -> Transferring Transferring -> PreTesting PreTesting -> Testing Testing -> Purging Purging -> Unloading Unloading -> BatchReady

非法操作直接返回失败:

Testing 状态不允许 StartLot Purging 状态不允许再次 SOT Resetting 状态不允许开始测试

三、PLC 信号事件化仍需完善

当前仍然主要依靠周期轮询和等待:

循环读取 PLC 判断是否满足条件 Task.Delay 继续读取

推荐保留轮询,同时增加信号变化事件:

PLC轮询服务 定时读取 PLC 快照 SignalChangeDetector 只发布发生变化的信号 StationWorkflowService 订阅需要的信号事件 WaitForCondition 作为超时和异常恢复兜底

不能完全删除轮询,因为工业现场必须具备:

  • 周期性心跳
  • 通讯断线检测
  • 信号一致性校验
  • 事件丢失恢复
  • 初始化后的完整快照

四、生命周期释放还需要补齐

目前StationLifecycleServiceStationWorkflowServiceStationCommandMailbox都有释放逻辑,但需要确认:

  • 工站 ViewModel 销毁时是否调用DisposeAsync
  • 页面关闭时是否停止流水线
  • PLC 轮询事件是否取消订阅
  • 自动化回调是否解除注册
  • CancellationTokenSource 是否全部释放
  • TCP 连接是否等待后台线程退出

否则长时间运行或重复打开页面可能出现:

  • 后台 Worker 残留
  • 事件重复订阅
  • 同一工站重复执行
  • 内存泄漏
  • 关闭软件时进程无法退出

五、日志和诊断还可以进一步统一

当前已经有自动化日志、EAP 日志、电学故障日志和辅控故障日志,但建议统一增加:

OperationId RequestId StationId LotId ProductSN PipelineStage ThreadId 当前状态 PLC信号快照

尤其是 PLC 等待日志,应统一记录:

等待条件: 上料位U相器件检测 = false 上料位V相器件检测 = false 吹扫完成标志位 = 5 当前值: 上料位U相器件检测 = true 上料位V相器件检测 = false 吹扫完成标志位 = 3

满足后记录:

PLC等待条件已全部满足,进入下一阶段

这对现场定位“为什么一直不搬运”非常重要。


六、建议的后续优化顺序

建议按以下顺序继续,每一步完成后上机验证:

  1. StationCommandMailbox从 ViewModel 目录迁移到Services.Workflow
  2. 将硬件访问从 UI Dispatcher 中分离
  3. 增加统一StationDeviceContext
  4. 增加 PLC、主控板和负载板资源锁
  5. 将自动化命令核心逻辑迁移到StationAutomationService
  6. 将 JSON/TCP 协议解析从AutomationBusinessHandler中拆出
  7. 增加自动化请求幂等缓存
  8. MainWindow的工站查找改成服务注册表
  9. 建立独立StationEapService
  10. 增加完整的服务释放和异常恢复
  11. 统一 PLC 等待日志和状态快照
  12. 最后启用严格状态机,拒绝非法跳转

结论:

当前架构已经比最初明显改善,但还没有完全达到工业级标准。最优先需要处理的是:

UI线程与后台业务分离 硬件资源互斥 自动化请求幂等 MainWindow与ViewModel解耦 Automation/EAP协议彻底分离

这些问题比继续拆分.partial.cs文件更重要。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询