欢迎光临
我们一直在努力

StateMachine — 状态机框架

BasicMethod.StateMachine — 状态机框架

定位:BasicMethod.Map 的状态机基础框架模块
核心能力:4 种状态转换模式 + 4 个通用组件 + 2 个预定义状态枚举
设计哲学:零外部依赖,纯 .NET 基础类库
适用场景:工作流编排、执行单元生命周期管理、事件驱动协调、线性处理管道


1. 概述

BasicMethod.StateMachine 是一个零外部依赖的通用状态机基础框架。它解决了工作流/执行单元在不同场景下需要不同状态转换模式的问题,提供四种正交的状态机模式,覆盖从简单的条件转换到复杂的异步事件驱动的全场景。

问题

传统方式下,每个需要状态管理的模块都要自行实现状态转换逻辑,导致大量重复代码:

#mermaid-svg-gJtO3HYgBd7O5FA3{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gJtO3HYgBd7O5FA3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gJtO3HYgBd7O5FA3 .error-icon{fill:#552222;}#mermaid-svg-gJtO3HYgBd7O5FA3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gJtO3HYgBd7O5FA3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gJtO3HYgBd7O5FA3 .marker.cross{stroke:#333333;}#mermaid-svg-gJtO3HYgBd7O5FA3 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gJtO3HYgBd7O5FA3 p{margin:0;}#mermaid-svg-gJtO3HYgBd7O5FA3 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-gJtO3HYgBd7O5FA3 .cluster-label text{fill:#333;}#mermaid-svg-gJtO3HYgBd7O5FA3 .cluster-label span{color:#333;}#mermaid-svg-gJtO3HYgBd7O5FA3 .cluster-label span p{background-color:transparent;}#mermaid-svg-gJtO3HYgBd7O5FA3 .label text,#mermaid-svg-gJtO3HYgBd7O5FA3 span{fill:#333;color:#333;}#mermaid-svg-gJtO3HYgBd7O5FA3 .node rect,#mermaid-svg-gJtO3HYgBd7O5FA3 .node circle,#mermaid-svg-gJtO3HYgBd7O5FA3 .node ellipse,#mermaid-svg-gJtO3HYgBd7O5FA3 .node polygon,#mermaid-svg-gJtO3HYgBd7O5FA3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gJtO3HYgBd7O5FA3 .rough-node .label text,#mermaid-svg-gJtO3HYgBd7O5FA3 .node .label text,#mermaid-svg-gJtO3HYgBd7O5FA3 .image-shape .label,#mermaid-svg-gJtO3HYgBd7O5FA3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-gJtO3HYgBd7O5FA3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gJtO3HYgBd7O5FA3 .rough-node .label,#mermaid-svg-gJtO3HYgBd7O5FA3 .node .label,#mermaid-svg-gJtO3HYgBd7O5FA3 .image-shape .label,#mermaid-svg-gJtO3HYgBd7O5FA3 .icon-shape .label{text-align:center;}#mermaid-svg-gJtO3HYgBd7O5FA3 .node.clickable{cursor:pointer;}#mermaid-svg-gJtO3HYgBd7O5FA3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gJtO3HYgBd7O5FA3 .arrowheadPath{fill:#333333;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gJtO3HYgBd7O5FA3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gJtO3HYgBd7O5FA3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gJtO3HYgBd7O5FA3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gJtO3HYgBd7O5FA3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gJtO3HYgBd7O5FA3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gJtO3HYgBd7O5FA3 .cluster text{fill:#333;}#mermaid-svg-gJtO3HYgBd7O5FA3 .cluster span{color:#333;}#mermaid-svg-gJtO3HYgBd7O5FA3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gJtO3HYgBd7O5FA3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gJtO3HYgBd7O5FA3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-gJtO3HYgBd7O5FA3 .icon-shape,#mermaid-svg-gJtO3HYgBd7O5FA3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gJtO3HYgBd7O5FA3 .icon-shape p,#mermaid-svg-gJtO3HYgBd7O5FA3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gJtO3HYgBd7O5FA3 .icon-shape .label rect,#mermaid-svg-gJtO3HYgBd7O5FA3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gJtO3HYgBd7O5FA3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gJtO3HYgBd7O5FA3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gJtO3HYgBd7O5FA3 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

❌ 传统方式:每模块自实现

模块 A自实现状态机

模块 B自实现状态机

模块 C自实现状态机

模块 D自实现状态机

解决方案

基于四种正交的状态机模式 + 通用组件,统一状态管理:

#mermaid-svg-GmdFG1vdR0xms9HK{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GmdFG1vdR0xms9HK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GmdFG1vdR0xms9HK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GmdFG1vdR0xms9HK .error-icon{fill:#552222;}#mermaid-svg-GmdFG1vdR0xms9HK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GmdFG1vdR0xms9HK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GmdFG1vdR0xms9HK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GmdFG1vdR0xms9HK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GmdFG1vdR0xms9HK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GmdFG1vdR0xms9HK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GmdFG1vdR0xms9HK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GmdFG1vdR0xms9HK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GmdFG1vdR0xms9HK .marker.cross{stroke:#333333;}#mermaid-svg-GmdFG1vdR0xms9HK svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GmdFG1vdR0xms9HK p{margin:0;}#mermaid-svg-GmdFG1vdR0xms9HK .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-GmdFG1vdR0xms9HK .cluster-label text{fill:#333;}#mermaid-svg-GmdFG1vdR0xms9HK .cluster-label span{color:#333;}#mermaid-svg-GmdFG1vdR0xms9HK .cluster-label span p{background-color:transparent;}#mermaid-svg-GmdFG1vdR0xms9HK .label text,#mermaid-svg-GmdFG1vdR0xms9HK span{fill:#333;color:#333;}#mermaid-svg-GmdFG1vdR0xms9HK .node rect,#mermaid-svg-GmdFG1vdR0xms9HK .node circle,#mermaid-svg-GmdFG1vdR0xms9HK .node ellipse,#mermaid-svg-GmdFG1vdR0xms9HK .node polygon,#mermaid-svg-GmdFG1vdR0xms9HK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GmdFG1vdR0xms9HK .rough-node .label text,#mermaid-svg-GmdFG1vdR0xms9HK .node .label text,#mermaid-svg-GmdFG1vdR0xms9HK .image-shape .label,#mermaid-svg-GmdFG1vdR0xms9HK .icon-shape .label{text-anchor:middle;}#mermaid-svg-GmdFG1vdR0xms9HK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GmdFG1vdR0xms9HK .rough-node .label,#mermaid-svg-GmdFG1vdR0xms9HK .node .label,#mermaid-svg-GmdFG1vdR0xms9HK .image-shape .label,#mermaid-svg-GmdFG1vdR0xms9HK .icon-shape .label{text-align:center;}#mermaid-svg-GmdFG1vdR0xms9HK .node.clickable{cursor:pointer;}#mermaid-svg-GmdFG1vdR0xms9HK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GmdFG1vdR0xms9HK .arrowheadPath{fill:#333333;}#mermaid-svg-GmdFG1vdR0xms9HK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GmdFG1vdR0xms9HK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GmdFG1vdR0xms9HK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GmdFG1vdR0xms9HK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GmdFG1vdR0xms9HK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GmdFG1vdR0xms9HK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GmdFG1vdR0xms9HK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GmdFG1vdR0xms9HK .cluster text{fill:#333;}#mermaid-svg-GmdFG1vdR0xms9HK .cluster span{color:#333;}#mermaid-svg-GmdFG1vdR0xms9HK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GmdFG1vdR0xms9HK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GmdFG1vdR0xms9HK rect.text{fill:none;stroke-width:0;}#mermaid-svg-GmdFG1vdR0xms9HK .icon-shape,#mermaid-svg-GmdFG1vdR0xms9HK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GmdFG1vdR0xms9HK .icon-shape p,#mermaid-svg-GmdFG1vdR0xms9HK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GmdFG1vdR0xms9HK .icon-shape .label rect,#mermaid-svg-GmdFG1vdR0xms9HK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GmdFG1vdR0xms9HK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GmdFG1vdR0xms9HK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GmdFG1vdR0xms9HK :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

✅ StateMachine 方式:统一框架

StateMachine统一框架

Conditional条件转换

Sequential顺序处理

Lifecycle生命周期

AsyncEvent异步事件

通用组件Store/Pause/Scope/Session


2. 四种状态机模式

2.1 ConditionalStateMachine — 条件转换状态机

核心特征:通过 TryTransitionTo/TryTransitionFrom 进行状态转换,支持条件验证和时间追踪。

适用场景:执行状态管理(Pending→Running→Completed/Faulted)、工作流编排、资源生命周期管理。

状态转换图:

#mermaid-svg-WizoKVlDztOxwWpn{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WizoKVlDztOxwWpn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WizoKVlDztOxwWpn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WizoKVlDztOxwWpn .error-icon{fill:#552222;}#mermaid-svg-WizoKVlDztOxwWpn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WizoKVlDztOxwWpn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WizoKVlDztOxwWpn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WizoKVlDztOxwWpn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WizoKVlDztOxwWpn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WizoKVlDztOxwWpn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WizoKVlDztOxwWpn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WizoKVlDztOxwWpn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WizoKVlDztOxwWpn .marker.cross{stroke:#333333;}#mermaid-svg-WizoKVlDztOxwWpn svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WizoKVlDztOxwWpn p{margin:0;}#mermaid-svg-WizoKVlDztOxwWpn defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-WizoKVlDztOxwWpn g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-WizoKVlDztOxwWpn g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-WizoKVlDztOxwWpn g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-WizoKVlDztOxwWpn g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-WizoKVlDztOxwWpn g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-WizoKVlDztOxwWpn .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-WizoKVlDztOxwWpn .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-WizoKVlDztOxwWpn .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-WizoKVlDztOxwWpn .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-WizoKVlDztOxwWpn .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-WizoKVlDztOxwWpn .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-WizoKVlDztOxwWpn .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-WizoKVlDztOxwWpn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WizoKVlDztOxwWpn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WizoKVlDztOxwWpn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WizoKVlDztOxwWpn .edgeLabel .label text{fill:#333;}#mermaid-svg-WizoKVlDztOxwWpn .label div .edgeLabel{color:#333;}#mermaid-svg-WizoKVlDztOxwWpn .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-WizoKVlDztOxwWpn .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-WizoKVlDztOxwWpn .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-WizoKVlDztOxwWpn .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-WizoKVlDztOxwWpn .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-WizoKVlDztOxwWpn .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WizoKVlDztOxwWpn .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WizoKVlDztOxwWpn #statediagram-barbEnd{fill:#333333;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WizoKVlDztOxwWpn .cluster-label,#mermaid-svg-WizoKVlDztOxwWpn .nodeLabel{color:#131300;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-WizoKVlDztOxwWpn .note-edge{stroke-dasharray:5;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-note text{fill:black;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram-note .nodeLabel{color:black;}#mermaid-svg-WizoKVlDztOxwWpn .statediagram .edgeLabel{color:red;}#mermaid-svg-WizoKVlDztOxwWpn #dependencyStart,#mermaid-svg-WizoKVlDztOxwWpn #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-WizoKVlDztOxwWpn .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WizoKVlDztOxwWpn :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

初始化

TryTransitionTo(StateA)

TryTransitionTo(StateB, condition)

TryTransitionFrom(StateA, StateC)

TryTransitionFrom(StateB, StateD)

Reset

Reset

InitialState

StateA

StateB

StateC

StateD

条件验证:condition(currentState) == true才允许转换

使用示例:

enum Status { Idle, Running, Completed, Faulted }

var sm = new ConditionalStateMachine<Status>(Status.Idle);

// 无条件转换
sm.TryTransitionTo(Status.Running); // true

// 条件转换:仅当当前状态为 Running 时才允许
sm.TryTransitionTo(Status.Completed, s => s == Status.Running); // true

// 期望状态验证:仅当当前状态为 Running 时才允许转换到 Faulted
sm.TryTransitionFrom(Status.Running, Status.Faulted); // false(当前是 Completed)

// 状态查询
Console.WriteLine(sm.CurrentState); // Completed
Console.WriteLine(sm.IsFinished); // false(需子类重写)
Console.WriteLine(sm.StartTime); // 初始化时间

与 LifecycleStateMachine 的区别:

特性ConditionalStateMachineLifecycleStateMachine
转换方式 条件验证 TryXxx 操作驱动 Permit/Fire
非法转换 返回 false 抛出 InvalidTransitionException
时间追踪 内置 StartTime/EndTime
状态快照 GetSnapshot()

2.2 SequentialStateMachine — 顺序处理状态机

核心特征:处理逐个输入的字符/Token 流,根据当前状态决定转换和累积输出。

适用场景:CommandTokenizer(char→token列表)、RestoreJsonObject(char→JSON)、ParseCondition(char→解析结果)、FindAdapter(Type→适配器)等线性处理管道。

处理流程:

累积上下文SequentialStateMachine调用方累积上下文SequentialStateMachine调用方#mermaid-svg-4PWBuDhOU2Bj09C3{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4PWBuDhOU2Bj09C3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4PWBuDhOU2Bj09C3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4PWBuDhOU2Bj09C3 .error-icon{fill:#552222;}#mermaid-svg-4PWBuDhOU2Bj09C3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4PWBuDhOU2Bj09C3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4PWBuDhOU2Bj09C3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4PWBuDhOU2Bj09C3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4PWBuDhOU2Bj09C3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4PWBuDhOU2Bj09C3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4PWBuDhOU2Bj09C3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4PWBuDhOU2Bj09C3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4PWBuDhOU2Bj09C3 .marker.cross{stroke:#333333;}#mermaid-svg-4PWBuDhOU2Bj09C3 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4PWBuDhOU2Bj09C3 p{margin:0;}#mermaid-svg-4PWBuDhOU2Bj09C3 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-4PWBuDhOU2Bj09C3 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-4PWBuDhOU2Bj09C3 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-4PWBuDhOU2Bj09C3 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-4PWBuDhOU2Bj09C3 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-4PWBuDhOU2Bj09C3 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-4PWBuDhOU2Bj09C3 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-4PWBuDhOU2Bj09C3 .sequenceNumber{fill:white;}#mermaid-svg-4PWBuDhOU2Bj09C3 #sequencenumber{fill:#333;}#mermaid-svg-4PWBuDhOU2Bj09C3 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-4PWBuDhOU2Bj09C3 .messageText{fill:#333;stroke:none;}#mermaid-svg-4PWBuDhOU2Bj09C3 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-4PWBuDhOU2Bj09C3 .labelText,#mermaid-svg-4PWBuDhOU2Bj09C3 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-4PWBuDhOU2Bj09C3 .loopText,#mermaid-svg-4PWBuDhOU2Bj09C3 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-4PWBuDhOU2Bj09C3 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-4PWBuDhOU2Bj09C3 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-4PWBuDhOU2Bj09C3 .noteText,#mermaid-svg-4PWBuDhOU2Bj09C3 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-4PWBuDhOU2Bj09C3 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-4PWBuDhOU2Bj09C3 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-4PWBuDhOU2Bj09C3 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-4PWBuDhOU2Bj09C3 .actorPopupMenu{position:absolute;}#mermaid-svg-4PWBuDhOU2Bj09C3 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-4PWBuDhOU2Bj09C3 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-4PWBuDhOU2Bj09C3 .actor-man circle,#mermaid-svg-4PWBuDhOU2Bj09C3 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-4PWBuDhOU2Bj09C3 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}alt[精确匹配][默认匹配][无匹配]loop[逐个输入]构造(initialState)When(StateA, condition, StateB, action)When(StateB, condition, StateC, action)Otherwise(StateDefault, action)Feed(input)查找匹配的 Transition执行 When 规则执行 Otherwise 规则return false执行 Action(input, context)return trueComplete(resultSelector)返回最终结果

使用示例:

// 示例:简单的 Tokenizer
enum TokenizerState { NORMAL, IN_QUOTE }

var sm = new SequentialStateMachine<char, StringBuilder, List<string>>(
(int)TokenizerState.NORMAL);

// 注册转换规则
sm.When((int)TokenizerState.NORMAL, c => c == '"',
(int)TokenizerState.IN_QUOTE);

sm.When((int)TokenizerState.NORMAL, c => char.IsWhiteSpace(c),
(int)TokenizerState.NORMAL, (c, ctx) => FlushToken(ctx));

sm.When((int)TokenizerState.NORMAL, c => true,
(int)TokenizerState.NORMAL, (c, ctx) => ctx.Append(c));

sm.When((int)TokenizerState.IN_QUOTE, c => c == '"',
(int)TokenizerState.NORMAL, (c, ctx) => FlushToken(ctx));

sm.Otherwise((int)TokenizerState.NORMAL);

// 处理输入
foreach (char c in input) sm.Feed(c);

// 获取结果
var tokens = sm.Complete(ctx => ExtractTokens(ctx));


2.3 LifecycleStateMachine — 生命周期状态机

核心特征:通过操作触发状态转换,伴随副作用,可检测非法转换。

适用场景:MiddlewarePipeline(Use/Build/Clear)、CommandRouter(Register/Unregister/SetActive)等具有明确生命周期阶段的管理类。

状态转换图:

#mermaid-svg-Sv5fIT531wBU5G3u{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Sv5fIT531wBU5G3u .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Sv5fIT531wBU5G3u .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Sv5fIT531wBU5G3u .error-icon{fill:#552222;}#mermaid-svg-Sv5fIT531wBU5G3u .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Sv5fIT531wBU5G3u .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Sv5fIT531wBU5G3u .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Sv5fIT531wBU5G3u .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Sv5fIT531wBU5G3u .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Sv5fIT531wBU5G3u .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Sv5fIT531wBU5G3u .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Sv5fIT531wBU5G3u .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Sv5fIT531wBU5G3u .marker.cross{stroke:#333333;}#mermaid-svg-Sv5fIT531wBU5G3u svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Sv5fIT531wBU5G3u p{margin:0;}#mermaid-svg-Sv5fIT531wBU5G3u defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-Sv5fIT531wBU5G3u g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-Sv5fIT531wBU5G3u g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-Sv5fIT531wBU5G3u g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-Sv5fIT531wBU5G3u g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-Sv5fIT531wBU5G3u g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-Sv5fIT531wBU5G3u .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-Sv5fIT531wBU5G3u .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-Sv5fIT531wBU5G3u .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-Sv5fIT531wBU5G3u .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Sv5fIT531wBU5G3u .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-Sv5fIT531wBU5G3u .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-Sv5fIT531wBU5G3u .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-Sv5fIT531wBU5G3u .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Sv5fIT531wBU5G3u .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Sv5fIT531wBU5G3u .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Sv5fIT531wBU5G3u .edgeLabel .label text{fill:#333;}#mermaid-svg-Sv5fIT531wBU5G3u .label div .edgeLabel{color:#333;}#mermaid-svg-Sv5fIT531wBU5G3u .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-Sv5fIT531wBU5G3u .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-Sv5fIT531wBU5G3u .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-Sv5fIT531wBU5G3u .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-Sv5fIT531wBU5G3u .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-Sv5fIT531wBU5G3u .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Sv5fIT531wBU5G3u .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Sv5fIT531wBU5G3u #statediagram-barbEnd{fill:#333333;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Sv5fIT531wBU5G3u .cluster-label,#mermaid-svg-Sv5fIT531wBU5G3u .nodeLabel{color:#131300;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-Sv5fIT531wBU5G3u .note-edge{stroke-dasharray:5;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-note text{fill:black;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram-note .nodeLabel{color:black;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagram .edgeLabel{color:red;}#mermaid-svg-Sv5fIT531wBU5G3u #dependencyStart,#mermaid-svg-Sv5fIT531wBU5G3u #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-Sv5fIT531wBU5G3u .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Sv5fIT531wBU5G3u :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

初始化

PermitReentry(Use)注册中间件

Permit(Build)构建管道

Permit(Clear)清空管道

PermitReentry(Use)❌ 抛出异常

UNBUILT

BUILT

Permit: 状态变更 + 副作用PermitReentry: 状态不变 + 副作用

使用示例:

enum PipelineOp { Use, Build, Clear }

var sm = new LifecycleStateMachine<PipelineOp>(UNBUILT);

// 注册许可转换
sm.Permit(UNBUILT, PipelineOp.Use, UNBUILT, () => middlewares.Add(mw));
sm.Permit(UNBUILT, PipelineOp.Build, BUILT, () => BuildPipeline());
sm.Permit(BUILT, PipelineOp.Clear, UNBUILT, () => ClearPipeline());

// 执行操作
sm.Fire(PipelineOp.Use); // 成功,状态不变
sm.Fire(PipelineOp.Build); // 成功,状态变为 BUILT
sm.Fire(PipelineOp.Build); // 抛出 InvalidTransitionException!

// 安全检查
if (sm.CanFire(PipelineOp.Clear))
sm.Fire(PipelineOp.Clear);

// 获取允许的操作
var allowed = sm.GetAllowedOperations();


2.4 AsyncEventStateMachine — 异步事件状态机

核心特征:等待外部事件触发,支持超时和取消。

适用场景:WaitAsync(等待控件状态变化)、事件驱动的异步协调、UI 自动化等待。

等待流程:

外部事件源超时计时器AsyncEventStateMachine调用方外部事件源超时计时器AsyncEventStateMachine调用方#mermaid-svg-aOrk6als6OmAZC55{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aOrk6als6OmAZC55 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aOrk6als6OmAZC55 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aOrk6als6OmAZC55 .error-icon{fill:#552222;}#mermaid-svg-aOrk6als6OmAZC55 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aOrk6als6OmAZC55 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aOrk6als6OmAZC55 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aOrk6als6OmAZC55 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aOrk6als6OmAZC55 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aOrk6als6OmAZC55 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aOrk6als6OmAZC55 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aOrk6als6OmAZC55 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aOrk6als6OmAZC55 .marker.cross{stroke:#333333;}#mermaid-svg-aOrk6als6OmAZC55 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aOrk6als6OmAZC55 p{margin:0;}#mermaid-svg-aOrk6als6OmAZC55 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-aOrk6als6OmAZC55 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-aOrk6als6OmAZC55 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-aOrk6als6OmAZC55 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-aOrk6als6OmAZC55 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-aOrk6als6OmAZC55 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-aOrk6als6OmAZC55 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-aOrk6als6OmAZC55 .sequenceNumber{fill:white;}#mermaid-svg-aOrk6als6OmAZC55 #sequencenumber{fill:#333;}#mermaid-svg-aOrk6als6OmAZC55 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-aOrk6als6OmAZC55 .messageText{fill:#333;stroke:none;}#mermaid-svg-aOrk6als6OmAZC55 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-aOrk6als6OmAZC55 .labelText,#mermaid-svg-aOrk6als6OmAZC55 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-aOrk6als6OmAZC55 .loopText,#mermaid-svg-aOrk6als6OmAZC55 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-aOrk6als6OmAZC55 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-aOrk6als6OmAZC55 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-aOrk6als6OmAZC55 .noteText,#mermaid-svg-aOrk6als6OmAZC55 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-aOrk6als6OmAZC55 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-aOrk6als6OmAZC55 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-aOrk6als6OmAZC55 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-aOrk6als6OmAZC55 .actorPopupMenu{position:absolute;}#mermaid-svg-aOrk6als6OmAZC55 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-aOrk6als6OmAZC55 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-aOrk6als6OmAZC55 .actor-man circle,#mermaid-svg-aOrk6als6OmAZC55 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-aOrk6als6OmAZC55 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}alt[事件匹配][超时][取消]WaitAsync(condition, timeoutMs, ct)状态: Idle → Waiting启动超时计时器返回 Task<TResult>OnEvent(eventArgs)condition(eventArgs) == true状态: Waiting → CompletedConvertEventToResult(eventArgs)Task 完成,返回 TResultOnTimeout()状态: Waiting → TimedOut抛出 TimeoutExceptionCancellationToken 触发状态: Waiting → Canceled抛出 OperationCanceledException

使用示例:

var awaiter = new AsyncEventStateMachine<EventArgs, bool>();

// 在另一个线程/事件处理器中触发
control.SomeEvent += (s, e) => awaiter.OnEvent(e);

// 等待事件发生(超时 5 秒)
try
{
var result = await awaiter.WaitAsync(
e => CheckCondition(control, expectedValue),
timeoutMs: 5000,
cancellationToken: ct);

Console.WriteLine("事件匹配成功");
}
catch (TimeoutException)
{
Console.WriteLine("等待超时");
}
catch (OperationCanceledException)
{
Console.WriteLine("等待被取消");
}

// 重置状态机,可重复使用
awaiter.Reset();


3. 预定义状态枚举

3.1 ExecutionStatus — 执行单元生命周期

描述一个执行单元(工作流、任务、操作等)从创建到完成的完整生命周期状态。

#mermaid-svg-CjA9NnyrsbZa2v4t{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CjA9NnyrsbZa2v4t .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CjA9NnyrsbZa2v4t .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CjA9NnyrsbZa2v4t .error-icon{fill:#552222;}#mermaid-svg-CjA9NnyrsbZa2v4t .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CjA9NnyrsbZa2v4t .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CjA9NnyrsbZa2v4t .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CjA9NnyrsbZa2v4t .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CjA9NnyrsbZa2v4t .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CjA9NnyrsbZa2v4t .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CjA9NnyrsbZa2v4t .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CjA9NnyrsbZa2v4t .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CjA9NnyrsbZa2v4t .marker.cross{stroke:#333333;}#mermaid-svg-CjA9NnyrsbZa2v4t svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CjA9NnyrsbZa2v4t p{margin:0;}#mermaid-svg-CjA9NnyrsbZa2v4t defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-CjA9NnyrsbZa2v4t g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-CjA9NnyrsbZa2v4t g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-CjA9NnyrsbZa2v4t g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-CjA9NnyrsbZa2v4t g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-CjA9NnyrsbZa2v4t g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-CjA9NnyrsbZa2v4t .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-CjA9NnyrsbZa2v4t .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-CjA9NnyrsbZa2v4t .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-CjA9NnyrsbZa2v4t .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-CjA9NnyrsbZa2v4t .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-CjA9NnyrsbZa2v4t .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-CjA9NnyrsbZa2v4t .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-CjA9NnyrsbZa2v4t .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CjA9NnyrsbZa2v4t .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CjA9NnyrsbZa2v4t .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CjA9NnyrsbZa2v4t .edgeLabel .label text{fill:#333;}#mermaid-svg-CjA9NnyrsbZa2v4t .label div .edgeLabel{color:#333;}#mermaid-svg-CjA9NnyrsbZa2v4t .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-CjA9NnyrsbZa2v4t .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-CjA9NnyrsbZa2v4t .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-CjA9NnyrsbZa2v4t .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-CjA9NnyrsbZa2v4t .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-CjA9NnyrsbZa2v4t .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CjA9NnyrsbZa2v4t .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CjA9NnyrsbZa2v4t #statediagram-barbEnd{fill:#333333;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CjA9NnyrsbZa2v4t .cluster-label,#mermaid-svg-CjA9NnyrsbZa2v4t .nodeLabel{color:#131300;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-CjA9NnyrsbZa2v4t .note-edge{stroke-dasharray:5;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-note text{fill:black;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram-note .nodeLabel{color:black;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagram .edgeLabel{color:red;}#mermaid-svg-CjA9NnyrsbZa2v4t #dependencyStart,#mermaid-svg-CjA9NnyrsbZa2v4t #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-CjA9NnyrsbZa2v4t .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CjA9NnyrsbZa2v4t :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

开始执行

取消

暂停

恢复

完成

失败

超时

取消

Pending

Running

Cancelled

Paused

Completed

Failed

Timeout

状态值说明
Pending 0 待执行 — 初始状态,尚未开始
Running 1 执行中 — 正在执行
Completed 2 已完成 — 执行成功
Failed 3 执行失败 — 发生错误
Cancelled 4 已取消 — 被外部取消
Paused 5 已暂停 — 执行被暂停(可恢复)
Timeout 6 超时 — 超过指定时间未完成

3.2 NodeStatus — 工作流节点状态

描述工作流图中单个节点(步骤/活动)的执行状态,在 ExecutionStatus 基础上增加 Skipped 状态。

#mermaid-svg-fjCFuEbD9ixCLvEP{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fjCFuEbD9ixCLvEP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fjCFuEbD9ixCLvEP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fjCFuEbD9ixCLvEP .error-icon{fill:#552222;}#mermaid-svg-fjCFuEbD9ixCLvEP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fjCFuEbD9ixCLvEP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fjCFuEbD9ixCLvEP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fjCFuEbD9ixCLvEP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fjCFuEbD9ixCLvEP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fjCFuEbD9ixCLvEP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fjCFuEbD9ixCLvEP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fjCFuEbD9ixCLvEP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fjCFuEbD9ixCLvEP .marker.cross{stroke:#333333;}#mermaid-svg-fjCFuEbD9ixCLvEP svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fjCFuEbD9ixCLvEP p{margin:0;}#mermaid-svg-fjCFuEbD9ixCLvEP defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-fjCFuEbD9ixCLvEP g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-fjCFuEbD9ixCLvEP g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-fjCFuEbD9ixCLvEP g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-fjCFuEbD9ixCLvEP g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-fjCFuEbD9ixCLvEP g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-fjCFuEbD9ixCLvEP .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-fjCFuEbD9ixCLvEP .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-fjCFuEbD9ixCLvEP .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-fjCFuEbD9ixCLvEP .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-fjCFuEbD9ixCLvEP .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-fjCFuEbD9ixCLvEP .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-fjCFuEbD9ixCLvEP .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-fjCFuEbD9ixCLvEP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fjCFuEbD9ixCLvEP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fjCFuEbD9ixCLvEP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fjCFuEbD9ixCLvEP .edgeLabel .label text{fill:#333;}#mermaid-svg-fjCFuEbD9ixCLvEP .label div .edgeLabel{color:#333;}#mermaid-svg-fjCFuEbD9ixCLvEP .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-fjCFuEbD9ixCLvEP .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-fjCFuEbD9ixCLvEP .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-fjCFuEbD9ixCLvEP .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-fjCFuEbD9ixCLvEP .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-fjCFuEbD9ixCLvEP .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fjCFuEbD9ixCLvEP .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fjCFuEbD9ixCLvEP #statediagram-barbEnd{fill:#333333;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fjCFuEbD9ixCLvEP .cluster-label,#mermaid-svg-fjCFuEbD9ixCLvEP .nodeLabel{color:#131300;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-fjCFuEbD9ixCLvEP .note-edge{stroke-dasharray:5;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-note text{fill:black;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram-note .nodeLabel{color:black;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagram .edgeLabel{color:red;}#mermaid-svg-fjCFuEbD9ixCLvEP #dependencyStart,#mermaid-svg-fjCFuEbD9ixCLvEP #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-fjCFuEbD9ixCLvEP .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fjCFuEbD9ixCLvEP :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

开始执行

条件不满足

暂停

恢复

完成

失败

超时

Pending

Running

Skipped

Paused

Completed

Failed

Timeout

状态值说明
Pending 0 待执行 — 初始状态,尚未开始
Running 1 执行中 — 正在执行
Completed 2 已完成 — 执行成功
Failed 3 执行失败 — 发生错误
Skipped 4 已跳过 — 因条件不满足被跳过
Paused 5 已暂停 — 执行被暂停(可恢复)
Timeout 6 超时 — 超过指定时间未完成

4. 通用组件

4.1 StateMachineStore — 状态机存储

管理多个 ConditionalStateMachine 实例,支持 TTL 自动清理。

var store = new StateMachineStore<ExecutionStatus>
{
MaxCapacity = 1000,
StateRetentionPeriod = TimeSpan.FromMinutes(5)
};

// 获取或创建状态机
var sm = store.GetOrCreate("execution-1");
sm.TryTransitionTo(ExecutionStatus.Running);

// 批量操作
store.CleanupFinished(); // 清理已结束的实例
var activeIds = store.GetActiveIds(); // 获取活跃实例

4.2 PauseHandle / PauseManager — 暂停/恢复控制

提供两级暂停控制:

  • PauseHandle:单实例暂停/恢复,基于 TaskCompletionSource 实现高效异步等待
  • PauseManager:全局暂停(Interlocked)+ 局部暂停(作用域)

// PauseHandle — 单实例暂停
var handle = new PauseHandle();

// 在异步方法中等待暂停
await handle.WaitIfPausedAsync(cancellationToken);

// 在其他地方控制暂停/恢复
handle.Pause();
handle.Resume();

// PauseManager — 全局/局部暂停
var pm = new PauseManager();

// 全局暂停
pm.RequestGlobalPause();
await pm.WaitForResumeAsync(null, CancellationToken.None);

// 局部暂停(作用域级别)
pm.RequestLocalPause("scope-1");
await pm.WaitForResumeAsync("scope-1", CancellationToken.None);

4.3 ScopeStateManager — 作用域状态管理器

支持嵌套作用域,每个作用域可独立管理状态。

var manager = new ScopeStateManager<ExecutionStatus>();

// 全局状态
manager.Global.TryTransitionTo(ExecutionStatus.Running);

// 创建作用域
var scope = manager.CreateScope("workflow-1");
scope.TryTransitionTo(ExecutionStatus.Running);

// 获取作用域
var s = manager.GetScope("workflow-1");

// 释放作用域
manager.ReleaseScope("workflow-1");

4.4 SessionManagerStateMachine — 会话管理器状态机

一站式会话管理:集成 ExecutionStateMachineBase + CancellationTokenSource + PauseManager。

var manager = new SessionManagerStateMachine<ExecutionStatus>(
maxCapacity: 1000,
retentionPeriod: TimeSpan.FromMinutes(5));

// 创建会话
var session = manager.CreateSession(
"session-1",
ExecutionStatus.Pending,
ExecutionStatus.Running,
ExecutionStatus.Paused);

session.MarkRunning(); // Pending → Running
session.MarkPaused(); // Running → Paused
session.MarkRunning(); // Paused → Running
session.MarkCompleted(); // Running → Completed

// 取消会话
manager.CancelSession("session-1");

// 清理已结束会话
manager.CleanupFinished();

// 暂停/恢复
manager.RequestGlobalPause();
manager.ResumeGlobalPause();


5. 基础设施

5.1 接口继承体系

#mermaid-svg-E1mMIdMg9c4N22JC{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-E1mMIdMg9c4N22JC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-E1mMIdMg9c4N22JC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-E1mMIdMg9c4N22JC .error-icon{fill:#552222;}#mermaid-svg-E1mMIdMg9c4N22JC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-E1mMIdMg9c4N22JC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-E1mMIdMg9c4N22JC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-E1mMIdMg9c4N22JC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-E1mMIdMg9c4N22JC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-E1mMIdMg9c4N22JC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-E1mMIdMg9c4N22JC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-E1mMIdMg9c4N22JC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-E1mMIdMg9c4N22JC .marker.cross{stroke:#333333;}#mermaid-svg-E1mMIdMg9c4N22JC svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-E1mMIdMg9c4N22JC p{margin:0;}#mermaid-svg-E1mMIdMg9c4N22JC g.classGroup text{fill:#9370DB;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-E1mMIdMg9c4N22JC g.classGroup text .title{font-weight:bolder;}#mermaid-svg-E1mMIdMg9c4N22JC .cluster-label text{fill:#333;}#mermaid-svg-E1mMIdMg9c4N22JC .cluster-label span{color:#333;}#mermaid-svg-E1mMIdMg9c4N22JC .cluster-label span p{background-color:transparent;}#mermaid-svg-E1mMIdMg9c4N22JC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-E1mMIdMg9c4N22JC .cluster text{fill:#333;}#mermaid-svg-E1mMIdMg9c4N22JC .cluster span{color:#333;}#mermaid-svg-E1mMIdMg9c4N22JC .nodeLabel,#mermaid-svg-E1mMIdMg9c4N22JC .edgeLabel{color:#131300;}#mermaid-svg-E1mMIdMg9c4N22JC .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-E1mMIdMg9c4N22JC .label text{fill:#131300;}#mermaid-svg-E1mMIdMg9c4N22JC .labelBkg{background:#ECECFF;}#mermaid-svg-E1mMIdMg9c4N22JC .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-E1mMIdMg9c4N22JC .classTitle{font-weight:bolder;}#mermaid-svg-E1mMIdMg9c4N22JC .node rect,#mermaid-svg-E1mMIdMg9c4N22JC .node circle,#mermaid-svg-E1mMIdMg9c4N22JC .node ellipse,#mermaid-svg-E1mMIdMg9c4N22JC .node polygon,#mermaid-svg-E1mMIdMg9c4N22JC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-E1mMIdMg9c4N22JC .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC g.clickable{cursor:pointer;}#mermaid-svg-E1mMIdMg9c4N22JC g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-E1mMIdMg9c4N22JC g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-E1mMIdMg9c4N22JC .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-E1mMIdMg9c4N22JC .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-E1mMIdMg9c4N22JC .dashed-line{stroke-dasharray:3;}#mermaid-svg-E1mMIdMg9c4N22JC .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-E1mMIdMg9c4N22JC #compositionStart,#mermaid-svg-E1mMIdMg9c4N22JC .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC #compositionEnd,#mermaid-svg-E1mMIdMg9c4N22JC .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC #dependencyStart,#mermaid-svg-E1mMIdMg9c4N22JC .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC #dependencyStart,#mermaid-svg-E1mMIdMg9c4N22JC .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC #extensionStart,#mermaid-svg-E1mMIdMg9c4N22JC .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC #extensionEnd,#mermaid-svg-E1mMIdMg9c4N22JC .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC #aggregationStart,#mermaid-svg-E1mMIdMg9c4N22JC .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC #aggregationEnd,#mermaid-svg-E1mMIdMg9c4N22JC .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC #lollipopStart,#mermaid-svg-E1mMIdMg9c4N22JC .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC #lollipopEnd,#mermaid-svg-E1mMIdMg9c4N22JC .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-E1mMIdMg9c4N22JC .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-E1mMIdMg9c4N22JC .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-E1mMIdMg9c4N22JC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-E1mMIdMg9c4N22JC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-E1mMIdMg9c4N22JC :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}#mermaid-svg-E1mMIdMg9c4N22JC .IStateMachine>*{fill:#e3f2fd!important;stroke:#1565c0!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IStateMachine span{fill:#e3f2fd!important;stroke:#1565c0!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IConditionalStateMachine>*{fill:#e8f5e9!important;stroke:#2e7d32!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IConditionalStateMachine span{fill:#e8f5e9!important;stroke:#2e7d32!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IStateMachineStore>*{fill:#fff3e0!important;stroke:#e65100!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IStateMachineStore span{fill:#fff3e0!important;stroke:#e65100!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IPauseHandle>*{fill:#f3e5f5!important;stroke:#6a1b9a!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IPauseHandle span{fill:#f3e5f5!important;stroke:#6a1b9a!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IPauseManager>*{fill:#fce4ec!important;stroke:#c62828!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IPauseManager span{fill:#fce4ec!important;stroke:#c62828!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IScopeStateManager>*{fill:#e0f2f1!important;stroke:#00695c!important;}#mermaid-svg-E1mMIdMg9c4N22JC .IScopeStateManager span{fill:#e0f2f1!important;stroke:#00695c!important;}

继承

«interface»

IStateMachine<TState>

+CurrentState TState

+StateChanged event

+Reset(TState) : void

«interface»

IConditionalStateMachine<TState>

+StartTime DateTime

+EndTime DateTime?

+IsActive bool

+IsFinished bool

+TryTransitionTo(TState, Func<TState,bool>?) : bool

+TryTransitionFrom(TState, TState) : bool

«interface»

IStateMachineStore<TState>

+Count int

+MaxCapacity int

+StateRetentionPeriod TimeSpan

+GetOrCreate(string) : IConditionalStateMachine

+Get(string) : IConditionalStateMachine?

+Remove(string) : bool

+GetActiveIds() : IEnumerable

+GetAllIds() : IEnumerable

+CleanupFinished() : int

«interface»

IPauseHandle

+IsPaused bool

+Pause() : void

+Resume() : void

+WaitIfPausedAsync(CancellationToken) : Task

«interface»

IPauseManager

+IsGloballyPaused bool

+RequestGlobalPause() : void

+ResumeGlobalPause() : void

+IsLocallyPaused(string) : bool

+RequestLocalPause(string) : void

+ResumeLocalPause(string) : void

+WaitForResumeAsync(string?, CancellationToken, int) : Task

«interface»

IScopeStateManager<TState>

+Global IConditionalStateMachine

+CreateScope(string) : IConditionalStateMachine

+GetScope(string) : IConditionalStateMachine?

+ReleaseScope(string) : bool

+GetScopeNames() : IReadOnlyCollection

5.2 ExecutionStateMachineBase — 执行状态机基类

封装执行单元(会话/节点/任务等)的通用生命周期状态管理,提供语义化的 MarkXxx() 方法。

// 会话场景
var session = new ExecutionStateMachineBase<ExecutionStatus>(
"session-1", ExecutionStatus.Pending,
ExecutionStatus.Running, ExecutionStatus.Paused);

session.MarkRunning(); // Pending → Running(递增 ExecutionCount)
session.MarkPaused(); // Running → Paused
session.MarkRunning(); // Paused → Running(递增 ExecutionCount)
session.MarkCompleted(); // Running → Completed

Console.WriteLine(session.Status); // Completed
Console.WriteLine(session.IsFinished); // true
Console.WriteLine(session.ExecutionCount); // 2
Console.WriteLine(session.Duration); // 持续时间

// 节点场景(支持重试)
var node = new ExecutionStateMachineBase<NodeStatus>(
"node-1", NodeStatus.Pending,
NodeStatus.Running, NodeStatus.Paused);

node.MarkRunning(); // Pending → Running
node.MarkFailed("Error occurred");
Console.WriteLine(node.ErrorMessage); // "Error occurred"

node.Reset(NodeStatus.Pending);
node.MarkRunning(); // Pending → Running(重试)
node.MarkCompleted(); // Running → Completed
Console.WriteLine(node.ExecutionCount); // 2

5.3 StateRecord — 状态记录

在状态追踪基础上,额外记录动作执行历史(CompletedActions/FailedActions)。

var record = new StateRecord<ExecutionStatus>("workflow-1");

record.SetStatus(ExecutionStatus.Running);
record.SetCurrentAction("LoadData");
record.AddCompletedAction("LoadData");
record.Complete(ExecutionStatus.Completed);

Console.WriteLine(record.Duration); // 持续时间
Console.WriteLine(record.CompletedActions.Count); // 1
Console.WriteLine(record.FailedActions.Count); // 0

// 获取不可变快照
var snapshot = record.GetSnapshot();

5.4 StateChangeEmitter — 状态变更事件触发器

消除多个状态机实现中重复的 event 声明与触发模式,提供线程安全的事件订阅/触发。

// 所有状态机内部统一使用 StateChangeEmitter
// 对外暴露标准 event 接口
var sm = new ConditionalStateMachine<ExecutionStatus>();

sm.StateChanged += (sender, args) =>
{
Console.WriteLine($"{args.FromState}{args.ToState}");
Console.WriteLine($"操作: {args.Operation}");
Console.WriteLine($"时间: {args.Timestamp}");
};

5.5 异常定义

异常说明
InvalidTransitionException 非法状态转换 — 当状态机不允许指定的转换时抛出
StateMachineConfigurationException 状态机配置异常 — 当状态机配置存在冲突或错误时抛出

6. 与 Map 其他模块的关系

#mermaid-svg-rhoomq0yov3zpQgY{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rhoomq0yov3zpQgY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rhoomq0yov3zpQgY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rhoomq0yov3zpQgY .error-icon{fill:#552222;}#mermaid-svg-rhoomq0yov3zpQgY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rhoomq0yov3zpQgY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rhoomq0yov3zpQgY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rhoomq0yov3zpQgY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rhoomq0yov3zpQgY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rhoomq0yov3zpQgY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rhoomq0yov3zpQgY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rhoomq0yov3zpQgY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rhoomq0yov3zpQgY .marker.cross{stroke:#333333;}#mermaid-svg-rhoomq0yov3zpQgY svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rhoomq0yov3zpQgY p{margin:0;}#mermaid-svg-rhoomq0yov3zpQgY .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-rhoomq0yov3zpQgY .cluster-label text{fill:#333;}#mermaid-svg-rhoomq0yov3zpQgY .cluster-label span{color:#333;}#mermaid-svg-rhoomq0yov3zpQgY .cluster-label span p{background-color:transparent;}#mermaid-svg-rhoomq0yov3zpQgY .label text,#mermaid-svg-rhoomq0yov3zpQgY span{fill:#333;color:#333;}#mermaid-svg-rhoomq0yov3zpQgY .node rect,#mermaid-svg-rhoomq0yov3zpQgY .node circle,#mermaid-svg-rhoomq0yov3zpQgY .node ellipse,#mermaid-svg-rhoomq0yov3zpQgY .node polygon,#mermaid-svg-rhoomq0yov3zpQgY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rhoomq0yov3zpQgY .rough-node .label text,#mermaid-svg-rhoomq0yov3zpQgY .node .label text,#mermaid-svg-rhoomq0yov3zpQgY .image-shape .label,#mermaid-svg-rhoomq0yov3zpQgY .icon-shape .label{text-anchor:middle;}#mermaid-svg-rhoomq0yov3zpQgY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rhoomq0yov3zpQgY .rough-node .label,#mermaid-svg-rhoomq0yov3zpQgY .node .label,#mermaid-svg-rhoomq0yov3zpQgY .image-shape .label,#mermaid-svg-rhoomq0yov3zpQgY .icon-shape .label{text-align:center;}#mermaid-svg-rhoomq0yov3zpQgY .node.clickable{cursor:pointer;}#mermaid-svg-rhoomq0yov3zpQgY .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rhoomq0yov3zpQgY .arrowheadPath{fill:#333333;}#mermaid-svg-rhoomq0yov3zpQgY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rhoomq0yov3zpQgY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rhoomq0yov3zpQgY .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rhoomq0yov3zpQgY .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rhoomq0yov3zpQgY .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rhoomq0yov3zpQgY .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rhoomq0yov3zpQgY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rhoomq0yov3zpQgY .cluster text{fill:#333;}#mermaid-svg-rhoomq0yov3zpQgY .cluster span{color:#333;}#mermaid-svg-rhoomq0yov3zpQgY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rhoomq0yov3zpQgY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rhoomq0yov3zpQgY rect.text{fill:none;stroke-width:0;}#mermaid-svg-rhoomq0yov3zpQgY .icon-shape,#mermaid-svg-rhoomq0yov3zpQgY .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rhoomq0yov3zpQgY .icon-shape p,#mermaid-svg-rhoomq0yov3zpQgY .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rhoomq0yov3zpQgY .icon-shape .label rect,#mermaid-svg-rhoomq0yov3zpQgY .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rhoomq0yov3zpQgY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rhoomq0yov3zpQgY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rhoomq0yov3zpQgY :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

互补模块

互补

互补

互补

互补

互补

无关模块

Functor恒等传播

DecisionEngine

GraphFoundation

SortMent编排执行顺序

Transformers类型变换 A→B

Block显式上下文

Container执行单元

Declarative声明式描述

Queue队列调度

StateMachine状态转换管理4种模式+通用组件什么时候做什么

模块关系
Transformers 互补 — Transformers 做类型变换 A→B,StateMachine 管理变换过程中的状态
Block 互补 — BlockContext 提供显式上下文,StateMachine 管理上下文的生命周期状态
Container 互补 — Container 提供执行单元,StateMachine 管理执行单元的状态转换
Declarative 互补 — Declarative 声明"有什么",StateMachine 管理"什么时候做什么"
Queue 互补 — Queue 管理任务排队,StateMachine 管理队列中每个任务的状态
Functor 无关 — Functor 做恒等传播,StateMachine 做状态转换
DecisionEngine 无关
GraphFoundation 无关
SortMent 无关 — SortMent 编排执行顺序,StateMachine 管理单个执行单元的状态

7. 文件结构

StateMachine/
├── StateMachine.csproj # 项目文件(零外部依赖)
├── StateMachine.Abstractions.cs # 接口定义 + 异常定义
├── ExecutionStatus.cs # 执行状态枚举(7 种状态)
├── NodeStatus.cs # 节点状态枚举(7 种状态)

├── ConditionalStateMachine.cs # 条件转换状态机
├── SequentialStateMachine.cs # 顺序处理状态机
├── LifecycleStateMachine.cs # 生命周期状态机
├── AsyncEventStateMachine.cs # 异步事件状态机

├── ExecutionStateMachineBase.cs # 执行状态机基类(MarkXxx 语义化方法)
├── StateRecord.cs # 状态记录(动作执行历史追踪)
├── StateChangeEmitter.cs # 状态变更事件触发器

├── StateMachineStore.cs # 状态机存储(多实例管理 + TTL)
├── PauseHandle.cs # 暂停句柄(单实例暂停/恢复)
├── PauseManager.cs # 暂停管理器(全局/局部暂停)
├── ScopeStateManager.cs # 作用域状态管理器
├── SessionManagerStateMachine.cs # 会话管理器状态机

└── BasicMethod.StateMachine功能介绍.md # 本文档

赞(0)
未经允许不得转载:171主机测评 » StateMachine — 状态机框架
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址