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

.NET Stateless同触发多守卫条件不满足时状态机报错问题求解

解决方案

针对你遇到的Stateless状态机触发报错问题,有两种简洁的解决方式,无需新增状态或触发,直接在现有配置上补充逻辑即可:

方案一:使用IgnoreIf忽略无效触发

当数据不存在时,直接忽略Initialized触发,让状态机保持在WaitingForData状态,不会抛出错误。修改后的状态配置如下:

var sm = new StateMachine<MyStates, MyTriggers>(MyStates.WaitingForData);

sm.Configure(MyStates.WaitingForData)
    .PermitIf(MyTriggers.Initialized, MyStates.RequestingNewData, 
        () => IsDataPresent() && !IsDataUpToDate())
    .PermitIf(MyTriggers.Initialized, MyStates.Complete, 
        () => IsDataPresent() && IsDataUpToDate())
    // 新增:数据不存在时忽略触发,状态保持不变
    .IgnoreIf(MyTriggers.Initialized, () => !IsDataPresent());

sm.Configure(MyStates.RequestingNewData)
    .OnEntryAsync(() =>
    {
        dataService.RequestNewDataAsync().Completed(task =>
        {
            sm.FireAsync(MyTriggers.NewDataArrived);
        });
        return Task.CompletedTask;
    })
    .Permit(MyTriggers.NewDataArrived, MyStates.Complete);

await sm.FireAsync(MyTriggers.Initialized);

方案二:使用PermitReentryIf重入当前状态

如果需要在数据不存在时触发WaitingForData的OnEntry逻辑(当前示例中没有,但后续可能添加),可以用重入当前状态的方式替代忽略:

sm.Configure(MyStates.WaitingForData)
    .PermitIf(MyTriggers.Initialized, MyStates.RequestingNewData, 
        () => IsDataPresent() && !IsDataUpToDate())
    .PermitIf(MyTriggers.Initialized, MyStates.Complete, 
        () => IsDataPresent() && IsDataUpToDate())
    // 新增:数据不存在时重入WaitingForData状态
    .PermitReentryIf(MyTriggers.Initialized, () => !IsDataPresent());

原理说明

Stateless要求同一状态下的同一触发,所有守卫条件必须覆盖所有可能的场景——要么允许过渡到某个状态,要么明确忽略/重入原状态。补充上述逻辑后,Initialized触发的所有分支都被覆盖,不会再因无匹配守卫而抛出InvalidOperationException。

内容的提问来源于stack exchange,提问作者AceGambit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:18:20