You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WorkflowCore简易工作流实现中步骤未触发问题求助

.NET Core WorkflowCore 文档状态工作流步骤未触发问题排查与修复

问题核心原因

  1. 工作流无持续监听逻辑:原工作流仅执行一次WaitFor和后续分支,完成后直接终止,无法捕获后续状态变更事件。
  2. 事件发布时机不匹配:启动工作流后立刻连续发布事件,此时工作流可能尚未进入WaitFor等待状态,导致事件丢失。
  3. 数据同步错误:外部直接修改内存中的Document对象,未同步到WorkflowCore的工作流上下文,导致工作流内部数据与外部不一致。
  4. 分支触发逻辑与预期不符:初始文档状态为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:00:15