99 lines
4.6 KiB
Plaintext
99 lines
4.6 KiB
Plaintext
// 协作任务示例:两个 ui.spawn 各自保留执行帧,worker 按指令量子轮转推进。
|
|
// 这里刻意重复增量语句,方便观察推进;量子按 VM 指令计数,不保证每个 increment 或每组 16 条之后恰好暂停。
|
|
// 取消不回滚已经发生的 steps 写入,单个原生调用仍是原子边界。
|
|
// 每个实例有独立 steps 状态,两个任务不会把局部帧或计数存储混在一起。
|
|
class CooperativeWork {
|
|
// 保存 ui.state 返回的原生可变计数,每个 CooperativeWork 构造传入不同对象。
|
|
steps: Object
|
|
// 普通零参数方法被 spawn 调度后可跨量子继续;每条 increment 更新同一实例的计数。
|
|
// 连续语句无需手工 yield,VM 按累计预算暂停,恢复时不会从第一条重放。
|
|
function run(self: CooperativeWork): Unit {
|
|
// 第 1 至 16 次增量:由 spawn 的调用续体依次执行,每次原生 increment 完成后才进入下一条。
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
// 第 17 至 32 次增量:若此前在 VM 指令量子处让出,恢复后从保存的位置继续,不重跑前面的增量。
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
// 第 33 至 48 次增量:依然修改当前实例的 steps,另一个 owner 的 run 有独立调用帧与计数。
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
// 第 49 至 64 次增量:正常走完才结束任务;中途取消保留已发生修改,不把计数回滚为零。
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
self.steps.increment()
|
|
}
|
|
}
|
|
// 创建两个独立 owner,虽然 key 都叫 work,也不会相互替换;owner/key 组合才是任务身份。
|
|
left = CooperativeWork(ui.state(0))
|
|
// 左右实例共享类和方法定义,但这里分别分配 state,不能仅凭相同 work key 判断会相互取消。
|
|
right = CooperativeWork(ui.state(0))
|
|
// owner 是 left,方法是绑定 left 的 run;Task 句柄只用于状态/取消/结果查询,不是第二个业务计数对象。
|
|
leftTask = ui.spawn(left,"work",left.run)
|
|
// 同 key 配不同 owner 构成不同任务身份,worker 可以在两个续体之间按量子交替推进。
|
|
rightTask = ui.spawn(right,"work",right.run)
|
|
// 状态文字绑定到 Task.status,业务进度可在 Console 查询 left/right 的 steps.value。
|
|
leftStatus = TextBlock("")
|
|
// 两份文字控件分别绑定各自 Task.status,完成时间和状态不会通过同一字段覆盖彼此。
|
|
rightStatus = TextBlock("")
|
|
leftStatus.bind("text",leftTask.status)
|
|
rightStatus.bind("text",rightTask.status)
|
|
// 仅展示任务状态,任务 owner 不是 Page;关闭页面不会仅因内容消失就撤掉这两个普通业务 owner 的任务。
|
|
page = Page()
|
|
page.title = "独立暂停调用"
|
|
page.render(Column(24,16,TextBlock("两个任务分别保存执行帧;在 REPL 查看 left.steps.value / right.steps.value",2),leftStatus,rightStatus))
|