diff --git a/docs/zh-CN/core/coroutine.md b/docs/zh-CN/core/coroutine.md index 371ba83..f10fa0f 100644 --- a/docs/zh-CN/core/coroutine.md +++ b/docs/zh-CN/core/coroutine.md @@ -175,6 +175,11 @@ var handle1 = scheduler.Run(coroutine); var handle2 = scheduler.StartTaskAsCoroutine(LoadDataAsync()); ``` +- `AsCoroutineInstruction()` 适合已经处在某个协程内部,只需要在当前位置等待 `Task` 完成的场景。 +- `ToCoroutineEnumerator()` 适合需要把 `Task` 先转换成 `IEnumerator`,再传给 `scheduler.Run(...)`、 + `Sequence(...)` 或其他只接受协程枚举器的 API。 +- `StartTaskAsCoroutine()` 适合已经持有 `CoroutineScheduler`,并希望把 `Task` 直接作为一个顶层协程启动的场景。 + ### 等待事件 ```csharp @@ -408,8 +413,8 @@ scheduler.OnCoroutineException += (handle, exception) => ### 如何等待异步方法? -可以直接 `yield return task.AsCoroutineInstruction()`,也可以使用 `scheduler.StartTaskAsCoroutine(task)` 启动一个以 Task -为主体的协程。 +在现有协程里等待 `Task` 时,优先使用 `yield return task.AsCoroutineInstruction()`;如果要把 `Task` 单独交给调度器启动,使用 +`scheduler.StartTaskAsCoroutine(task)`;如果中间还需要传给只接受协程枚举器的 API,则先调用 `task.ToCoroutineEnumerator()`。 ## 相关文档 diff --git a/docs/zh-CN/godot/coroutine.md b/docs/zh-CN/godot/coroutine.md index 80c6314..15171bf 100644 --- a/docs/zh-CN/godot/coroutine.md +++ b/docs/zh-CN/godot/coroutine.md @@ -103,7 +103,14 @@ public partial class MyNode : Node - `CancelWith(Node node1, Node node2)` - `CancelWith(params Node[] nodes)` -只要任一被监视的节点失效,包装后的协程就会停止继续枚举。 +`CancelWith(...)` 内部通过 `Timing.IsNodeAlive(...)` 判断节点是否仍然有效。只要任一被监视的节点出现以下任一情况,包装后的协程就会停止继续枚举: + +- 节点引用为 `null` +- Godot 实例已经失效或已被释放 +- 节点已进入 `queue_free` / `IsQueuedForDeletion()` +- 节点已退出场景树,`IsInsideTree()` 返回 `false` + +这意味着协程不只会在节点真正释放时停止;节点一旦退出场景树,下一次推进时也会停止。 ## Segment 分段 @@ -195,6 +202,10 @@ LoadSomethingAsync() .RunCoroutine(); ``` +- 已经在一个协程内部时,优先使用 `yield return task.AsCoroutineInstruction()`,这样可以直接把 `Task` 嵌入当前协程流程。 +- 如果要把一个现成的 `Task` 当作独立协程入口交给 Godot 协程系统运行,再使用 + `task.ToCoroutineEnumerator().RunCoroutine()`。 + ### 等待事件总线事件 可以通过事件总线等待业务事件: