WorkflowCore简易工作流实现中步骤未触发问题求助
.NET Core WorkflowCore 文档状态工作流步骤未触发问题排查与修复
问题核心原因
- 工作流无持续监听逻辑:原工作流仅执行一次
WaitFor和后续分支,完成后直接终止,无法捕获后续状态变更事件。 - 事件发布时机不匹配:启动工作流后立刻连续发布事件,此时工作流可能尚未进入
WaitFor等待状态,导致事件丢失。 - 数据同步错误:外部直接修改内存中的
Document对象,未同步到WorkflowCore的工作流上下文,导致工作流内部数据与外部不一致。 - 分支触发逻辑与预期不符:初始文档状态为
Unread,但第一个发布的事件是InProgress,导致工作流直接触发InProgress分支,而非预期的Unread分支。
修复方案
1. 修改工作流定义,添加循环监听
使用While节点让工作流持续等待事件,直到状态为Done或Deny时终止:
public class DocumentWorkflow : IWorkflow<Document> { public string Id => "DocumentWorkflow"; public int Version => 1; public void Build(IWorkflowBuilder<Document> builder) { builder .StartWith(context => ExecutionResult.Next()) // 循环监听,直到状态为终止状态 .While(data => data.Status != DocumentStatus.Done && data.Status != DocumentStatus.Deny) .Do(loop => loop .WaitFor("DocumentStatusChange", (data, context) => context.Workflow.Id, data => DateTime.Now) .Output(data => data.Status, step => (DocumentStatus)Enum.Parse(typeof(DocumentStatus), step.EventData.ToString())) .When(data => data.Status == DocumentStatus.Unread) .Do(then => then .StartWith<UnreadToInProgressStep>() .Input(step => step.Document, data => data)) .When(data => data.Status == DocumentStatus.InProgress) .Do(then => then .StartWith<InProgressToDoneStep>() .Input(step => step.Document, data => data)) .When(data => data.Status == DocumentStatus.Deny) .Do(then => then .StartWith<AnyToDenyStep>() .Input(step => step.Document, data => data)) ); } }
2. 调整事件发布逻辑
移除外部修改Document对象的代码,仅发布事件传递新状态,并添加短暂等待确保工作流处理完成:
private static void PublishStatusChange(IWorkflowHost host, string workflowId, DocumentStatus newStatus) { Console.WriteLine($"Publishing status change event: {newStatus}"); host.PublishEvent("DocumentStatusChange", workflowId, newStatus.ToString()).Wait(); // 等待工作流处理当前事件,避免连续发布导致丢失 Thread.Sleep(500); } // 主方法调用调整 var document = new Document { Title = "Sample Document", Status = DocumentStatus.Unread }; var workflowId = host.StartWorkflow("DocumentWorkflow", 1, document).Result; // 按顺序发布事件,测试流程 PublishStatusChange(host, workflowId, DocumentStatus.Unread); PublishStatusChange(host, workflowId, DocumentStatus.InProgress); PublishStatusChange(host, workflowId, DocumentStatus.Done);
3. 配置日志排查执行细节
添加控制台日志,查看工作流执行的详细过程,确认是否进入等待、捕获事件:
private static IServiceProvider ConfigureServices() { var services = new ServiceCollection(); services.AddLogging(logging => { logging.AddConsole(); logging.SetMinimumLevel(LogLevel.Debug); }); services.AddWorkflow(cfg => cfg.UsePersistence(sp=> new MemoryPersistenceProvider())); services.AddTransient<IWorkflow<Document>, DocumentWorkflow>(); services.AddTransient<UnreadToInProgressStep>(); services.AddTransient<InProgressToDoneStep>(); services.AddTransient<AnyToDenyStep>(); return services.BuildServiceProvider(); }
4. 修正步骤逻辑(可选)
如果你的需求是:当工作流收到某个状态事件时,自动执行状态转换(比如收到Unread事件就转到InProgress),可以保留原步骤逻辑;如果需要外部触发状态变更后工作流仅做业务处理,可调整步骤逻辑去掉状态转换代码。
验证结果
修复后,工作流会持续监听状态变更事件,每次事件触发后执行对应分支的步骤,直到状态变为Done或Deny时终止,控制台会输出各步骤的调试信息。
内容的提问来源于stack exchange,提问作者Mousa Ghajar Najafi
相关产品推荐
相关产品推荐

