Skip to Content

任务与 spawn(Task 与 Spawn)

spawn 将代码块立即投入执行,并返回一个 task。带值的块直接 return,块的类型就是 task<T>,不用先声明 async 函数。

spawn 块

async func main() -> int { val t = spawn { await 0.5s; print("块内跑完"); }; val n = spawn { await 0.5s; return 7; }; print(t.IsCompleted); val r = await n; print(r); await t; print(t.IsCompleted); return 0; }
False 块内跑完 7 True

第一个 spawn 是 void 块(task<void>),第二个带 return 7(task<int>)。print(t.IsCompleted) 打出 False(块还在睡),await n 拿到 7,await t 等它跑完后再查就是 True。

调度时机

spawn 的块立刻开跑,一路跑到自己的首个 await 为止才挂起让出,不是等主线到某个交错点才起跑。

async func main() -> int { val a = spawn { await 0.3s; print("A woke"); }; spawn { await 0.1s; print("B woke"); }; await a; return 0; }
$ mush --virtual-time run demo.ms B woke A woke

IsCompleted:唯一的成员面

t.IsCompleted 是当前 task 在脚本侧唯一的成员:完成、fault、取消协商都算终态。

捕获隔离

spawn 块可以读外层变量,但写不回流:块内对外层捕获变量的修改只活在块里,与同步 lambda(写穿透)不同。task 与主线的数据交换走返回值加 await,任务结果只能经 await 取得。

spawn cancel

spawn cancel ct { } 给块一个可取消环境,体内 cancel.requested / cancel.token 可用(见取消与超时)。

注意

  • spawn 块的失败经 await 传播:await 一个 fault 的 task,失败在 await 位冒出。
  • 不 await 的 spawn 是 fire-and-forget 语义,块照常会跑完。
  • 块内 return 的类型推断自首个 return,多路 return 类型须一致。
最后更新于 2026年10月10日