第 23/36 课 · 约 34 分钟
DAS 脚本状态机、边沿触发与恢复
用明确状态转换实现重复触发抑制,并用输入序列验证。
把状态转换写清楚
前置知识:自定义对象与有限循环。条件持续为真与刚刚变为真不同。阈值观察器可以每次满足都报告,也可以只在状态进入时报告。本课用虚构数值实现边沿检测,标记是本地程序状态,不是分布式锁或事务保证。
定义状态机
状态 0 表示阈值以下,1 表示已对阈值以上状态报告。0→1 报告一次,1→1 不报告,低于阈值恢复到 0。本例规定等于阈值既不触发也不重新准备,避免把 > 改成 >= 时无意改变语义。
可确定结果的测试程序
$feSequence = NewUserObj();
$feSequence.Set(0, 9);
$feSequence.Set(1, 11);
$feSequence.Set(2, 12);
$feSequence.Set(3, 8);
$feSequence.Set(4, 11);
$feThreshold = 10;
$feEdgeState = 0;
$feEdgeReports = 0;
$feStep = 0;
while ($feStep < 5) {
$feObserved = $feSequence.Get($feStep);
if ($feObserved > $feThreshold) {
if ($feEdgeState == 0) {
$feEdgeState = 1;
$feEdgeReports = $feEdgeReports + 1;
}
} else {
if ($feObserved < $feThreshold) {
$feEdgeState = 0;
}
}
$feStep = $feStep + 1;
}
MsgBox($feEdgeReports);
逐项推演
9 保持状态 0;11 进入 1,报告第一次;12 仍为 1;8 回到 0;最后 11 报告第二次。预期结果是 2。移入 Timer 时应跨回调保存状态,每次只处理一个样本,不能在每次回调开头重新设 state=0。
恢复与状态归属
状态必须绑定输入身份:股票、周期、账户、阈值变化都可能使旧解释失效。定义启动时已经高于阈值是立即报告,还是等待先低于阈值。缺失或过期数据应按未知/停用策略处理,不能默认为零。busy 可以抑制自行设计的顺序重复动作,但不保证多个独立回调间原子性,也不跨进程重启保存。
练习与参考解答
序列改为 11、10、11、9、11。本例参考结果仍为 2,因为等于阈值不重新准备。若要求等于也重新准备,明确修改规则,预期变成 3。更强的迟滞设计可用 >10 触发、<9 重置,中间区间保持状态。