From 4362989056d0b670ab2745d00b472a035e60f5a7 Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Thu, 12 Mar 2026 12:49:29 +0800 Subject: [PATCH] =?UTF-8?q?docs(coroutine):=20=E6=9B=B4=E6=96=B0=E5=8D=8F?= =?UTF-8?q?=E7=A8=8B=E7=9B=B8=E5=85=B3=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了 AsCoroutineInstruction()、ToCoroutineEnumerator() 和 StartTaskAsCoroutine() 的使用场景说明 - 优化了等待异步方法的文档描述,明确不同 API 的适用场景 - 详细说明了 CancelWith 方法的节点有效性判断机制和停止条件 - 补充了 Godot 协程中 Task 转协程的具体使用建议 --- docs/zh-CN/core/coroutine.md | 9 +++++++-- docs/zh-CN/godot/coroutine.md | 13 ++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) 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()`。 + ### 等待事件总线事件 可以通过事件总线等待业务事件: