diff --git a/MainModule/ViewModels/AutomatedTestingViewModel.cs b/MainModule/ViewModels/AutomatedTestingViewModel.cs index 9acdc20..4ce318c 100644 --- a/MainModule/ViewModels/AutomatedTestingViewModel.cs +++ b/MainModule/ViewModels/AutomatedTestingViewModel.cs @@ -135,7 +135,8 @@ namespace MainModule.ViewModels } /// - /// 执行异常流程(带并发保护,同一时间仅允许一次) + /// 执行异常流程(带并发保护,同一时间仅允许一次)。 + /// 如果正常流程正在运行,先取消并等待其停止,再执行异常流程。 /// private async Task TriggerErrorStepsAsync() { @@ -143,6 +144,34 @@ namespace MainModule.ViewModels _isRunningErrorSteps = true; try { + // 1. 如果正常流程正在运行,先停止它 + // IsStop == false 表示正在运行;IsStop == null 表示未启动或已结束 + if (_scopedContext.IsStop == false) + { + LoggerHelper.WarnWithNotify(TestStatus, $"[{TestStatus}] 报警触发,正在停止正常流程..."); + _stepRunning.stepCTS.Cancel(); + + // 等待 ShellViewModel 清理完毕(IsStop 变回 null、stepCTS 被重置) + // ExecuteMethodStep 内部硬编码使用 stepCTS.Token,必须等它重置后才能跑异常流程 + var deadline = DateTime.Now.AddSeconds(5); + while ((_scopedContext.IsStop != null || _stepRunning.stepCTS.IsCancellationRequested) + && DateTime.Now < deadline) + { + await Task.Delay(50); + } + + // 超时后仍未重置则强制重置,确保异常流程的设备命令能拿到有效 Token + if (_stepRunning.stepCTS.IsCancellationRequested) + { + _stepRunning.stepCTS = new CancellationTokenSource(); + _scopedContext.IsStop = null; + _scopedContext.RunState = "运行"; + } + + LoggerHelper.WarnWithNotify(TestStatus, $"[{TestStatus}] 正常流程已停止,开始执行异常流程"); + } + + // 2. 执行异常流程 await _stepRunning.ExecuteErrorSteps( _scopedContext.Program, cancellationToken: _stepRunning.errorStepCTS.Token);