using MainShell.Common; using MainShell.Recipe.Models; using MW.WorkFlow; using System; using System.Threading.Tasks; namespace MainShell.Process { public class ChipUnloadActivity : ActivityAbstractBase { private readonly TimeSpan _timeout; public ChipUnloadActivity(string name, TimeSpan? timeout = null) : base(name) { _timeout = timeout ?? TimeSpan.FromSeconds(30); } protected override async Task OnExecuteAsync(WorkflowContext context, ActivityControl activityControl) { activityControl.ThrowIfCancellationRequested(); PreparationAreaService preparationAreaService; if (!context.TryGetData(WorkflowContextKeys.PreparationAreaService, out preparationAreaService) || preparationAreaService == null) { throw new InvalidOperationException("未在工作流上下文中找到准备区服务。"); } CurrentChipStateService currentChipStateService; if (!context.TryGetData(WorkflowContextKeys.CurrentChipStateService, out currentChipStateService) || currentChipStateService == null) { throw new InvalidOperationException("未在工作流上下文中找到当前芯片状态服务。"); } AutoProductionRuntimeStateService autoProductionRuntimeStateService; if (!context.TryGetData(WorkflowContextKeys.AutoProductionRuntimeStateService, out autoProductionRuntimeStateService) || autoProductionRuntimeStateService == null) { throw new InvalidOperationException("未在工作流上下文中找到自动流程运行态服务。"); } if (currentChipStateService.CurrentState == CurrentChipLifecycleState.Empty) { autoProductionRuntimeStateService.SetCurrentChipRemainingCount(0); context.SetData(WorkflowContextKeys.CurrentChipState, CurrentChipLifecycleState.Empty); context.SetData(WorkflowContextKeys.PendingChipLoad, true); context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus); context.SetData(WorkflowContextKeys.CurrentChipRemainingCount, autoProductionRuntimeStateService.CurrentChipRemainingCount); return ActivityResult.Success; } currentChipStateService.SetState(CurrentChipLifecycleState.Unloading); context.SetData(WorkflowContextKeys.CurrentChipState, CurrentChipLifecycleState.Unloading); ChipPreparationRequest request = new ChipPreparationRequest { RecipeName = ResolveRecipeName(context), Action = ChipPreparationAction.Unload, SourceStepId = ResolveSourceStepId(context) }; string rejectReason; if (!preparationAreaService.TryRequestPrepare(request, out rejectReason)) { return Fail( context, MessageKey.ProcessStepFailedWithReason, new object[] { Name, string.IsNullOrWhiteSpace(rejectReason) ? "芯片下料请求失败。" : rejectReason }); } ChipPreparationWaitResult waitResult = await preparationAreaService.WaitUntilReadyAsync(_timeout, activityControl.CancellationToken).ConfigureAwait(false); if (!waitResult.Success) { if (waitResult.IsCanceled) { SetWorkflowFailure(context, string.IsNullOrWhiteSpace(waitResult.ErrorMessage) ? "芯片下料等待已取消。" : waitResult.ErrorMessage); return ActivityResult.Canceled; } return Fail( context, MessageKey.ProcessStepFailedWithReason, new object[] { Name, string.IsNullOrWhiteSpace(waitResult.ErrorMessage) ? "芯片下料等待失败。" : waitResult.ErrorMessage }); } if (!preparationAreaService.TryConsumeReady(out rejectReason)) { return Fail( context, MessageKey.ProcessStepFailedWithReason, new object[] { Name, string.IsNullOrWhiteSpace(rejectReason) ? "芯片下料结果消费失败。" : rejectReason }); } currentChipStateService.SetState(CurrentChipLifecycleState.Empty); autoProductionRuntimeStateService.SetCurrentChipRemainingCount(0); context.SetData(WorkflowContextKeys.PreparationAreaStatus, preparationAreaService.CurrentStatus); context.SetData(WorkflowContextKeys.CurrentChipState, CurrentChipLifecycleState.Empty); context.SetData(WorkflowContextKeys.PendingChipLoad, true); context.SetData(WorkflowContextKeys.CurrentChipRemainingCount, autoProductionRuntimeStateService.CurrentChipRemainingCount); return ActivityResult.Success; } private static string ResolveRecipeName(WorkflowContext context) { RecipeManager recipeManager; if (context.TryGetData(WorkflowContextKeys.RecipeManager, out recipeManager) && recipeManager != null && recipeManager.CurrentWaferRecipe != null) { return recipeManager.CurrentWaferRecipe.RecipeName; } return string.Empty; } private static string ResolveSourceStepId(WorkflowContext context) { string stepId; if (context.TryGetData(WorkflowContextKeys.CurrentStepId, out stepId)) { return stepId; } return string.Empty; } } }