Skip to content

refactor(coroutine): 优化任务协程扩展实现#29

Merged
GeWuYou merged 2 commits into
mainfrom
refactor/coroutine-extension-optimization
Feb 15, 2026
Merged

refactor(coroutine): 优化任务协程扩展实现#29
GeWuYou merged 2 commits into
mainfrom
refactor/coroutine-extension-optimization

Conversation

@GeWuYou

@GeWuYou GeWuYou commented Feb 15, 2026

Copy link
Copy Markdown
Owner
  • 将私有方法 CreateTaskCoroutine 替换为公共扩展方法 AsCoroutine
  • 简化 StartTaskAsCoroutine 方法实现,直接调用 AsCoroutine 扩展方法
  • 移除重复的私有方法定义,统一使用扩展方法模式
  • 提高代码可读性和复用性

Summary by Sourcery

Refactor task-to-coroutine handling to use public extension methods for creating coroutine enumerators and simplify coroutine startup APIs.

Enhancements:

  • Expose Task and Task to-coroutine converters as AsCoroutine extension methods for reuse across the codebase.
  • Simplify StartTaskAsCoroutine overloads to delegate directly to the AsCoroutine extensions instead of private helper methods.

- 将私有方法 CreateTaskCoroutine 替换为公共扩展方法 AsCoroutine
- 简化 StartTaskAsCoroutine 方法实现,直接调用 AsCoroutine 扩展方法
- 移除重复的私有方法定义,统一使用扩展方法模式
- 提高代码可读性和复用性
@sourcery-ai

sourcery-ai Bot commented Feb 15, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Refactors task-to-coroutine wiring by replacing private factory methods with public Task/Task extension methods, and simplifying the scheduler entry points to use those extensions, improving reuse and readability.

Sequence diagram for starting a Task as coroutine via AsCoroutine extension

sequenceDiagram
    participant CS as CoroutineScheduler
    participant T as Task
    participant Ext as TaskCoroutineExtensions
    participant WF as WaitForTask
    participant CH as CoroutineHandle

    CS->>T: StartTaskAsCoroutine(task)
    CS->>Ext: task.AsCoroutine()
    Ext->>T: AsCoroutineInstruction()
    T-->>Ext: WaitForTask instance
    Ext->>WF: create IEnumerator over WaitForTask
    Ext-->>CS: IEnumerator IYieldInstruction
    CS->>CS: Run(IEnumerator IYieldInstruction)
    CS-->>CH: CoroutineHandle
Loading

Class diagram for refactored task coroutine extensions

classDiagram
    class CoroutineScheduler {
        +CoroutineHandle Run(IEnumerator~IYieldInstruction~ routine)
        +CoroutineHandle StartTaskAsCoroutine(Task task)
        +CoroutineHandle StartTaskAsCoroutine~T~(Task~T~ task)
    }

    class TaskCoroutineExtensions {
        <<static>> TaskCoroutineExtensions
        +WaitForTask AsCoroutineInstruction(Task task)
        +WaitForTask~T~ AsCoroutineInstruction~T~(Task~T~ task)
        +IEnumerator~IYieldInstruction~ AsCoroutine(Task task)
        +IEnumerator~IYieldInstruction~ AsCoroutine~T~(Task~T~ task)
        +CoroutineHandle StartTaskAsCoroutine(CoroutineScheduler scheduler, Task task)
        +CoroutineHandle StartTaskAsCoroutine~T~(CoroutineScheduler scheduler, Task~T~ task)
    }

    class Task {
        +void Start()
    }

    class Task~T~ {
        +T Result
        +void Start()
    }

    class IYieldInstruction {
    }

    class WaitForTask {
        +Task task
    }

    class WaitForTask~T~ {
        +Task~T~ task
    }

    class CoroutineHandle {
    }

    Task <|-- Task~T~
    IYieldInstruction <|-- WaitForTask
    IYieldInstruction <|-- WaitForTask~T~

    CoroutineScheduler ..> CoroutineHandle
    CoroutineScheduler ..> Task
    CoroutineScheduler ..> Task~T~

    TaskCoroutineExtensions ..> Task : extends
    TaskCoroutineExtensions ..> Task~T~ : extends
    TaskCoroutineExtensions ..> WaitForTask
    TaskCoroutineExtensions ..> WaitForTask~T~
    TaskCoroutineExtensions ..> IYieldInstruction
    TaskCoroutineExtensions ..> CoroutineHandle
    TaskCoroutineExtensions ..> CoroutineScheduler

    CoroutineScheduler --> TaskCoroutineExtensions : uses extensions
Loading

File-Level Changes

Change Details Files
Refactor Task-to-coroutine creation into public extension methods and update scheduler helpers to consume them.
  • StartTaskAsCoroutine(CoroutineScheduler, Task) now calls the Task.AsCoroutine() extension instead of a private CreateTaskCoroutine helper.
  • StartTaskAsCoroutine(CoroutineScheduler, Task) now calls the Task.AsCoroutine() extension instead of a private generic CreateTaskCoroutine helper.
  • Replaces the private CreateTaskCoroutine(Task) helper with a public AsCoroutine(this Task) extension that yields the existing AsCoroutineInstruction() result.
  • Replaces the private generic CreateTaskCoroutine(Task) helper with a public AsCoroutine(this Task) extension that yields the existing AsCoroutineInstruction() result.
GFramework.Core/coroutine/extensions/TaskCoroutineExtensions.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • Exposing AsCoroutine(this Task ...) and AsCoroutine<T>(this Task<T> ...) as public extension methods changes the public API surface; consider whether these should remain internal/private helpers or be placed in a dedicated internal namespace to avoid unintended external usage.
  • The new AsCoroutine extension name is very close to AsCoroutineInstruction, which may be confusing at call sites; consider a more explicit name (e.g., ToCoroutineEnumerator) to distinguish between the yielded enumerator and the yield instruction wrapper.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Exposing `AsCoroutine(this Task ...)` and `AsCoroutine<T>(this Task<T> ...)` as public extension methods changes the public API surface; consider whether these should remain internal/private helpers or be placed in a dedicated internal namespace to avoid unintended external usage.
- The new `AsCoroutine` extension name is very close to `AsCoroutineInstruction`, which may be confusing at call sites; consider a more explicit name (e.g., `ToCoroutineEnumerator`) to distinguish between the yielded enumerator and the yield instruction wrapper.

## Individual Comments

### Comment 1
<location> `GFramework.Core/coroutine/extensions/TaskCoroutineExtensions.cs:58-60` </location>
<code_context>
     ///     创建等待Task的协程
     /// </summary>
-    private static IEnumerator<IYieldInstruction> CreateTaskCoroutine(Task task)
+    public static IEnumerator<IYieldInstruction> AsCoroutine(this Task task)
     {
         yield return task.AsCoroutineInstruction();
     }
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Consider adding a null check for the Task parameter to fail fast with a clearer exception.

As a public extension method, this can now be invoked on a null `Task`, leading to a `NullReferenceException` from `task.AsCoroutineInstruction()`. Adding a null guard (e.g., throw `ArgumentNullException`) would give a clearer error and match common extension-method conventions.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 58 to 60
public static IEnumerator<IYieldInstruction> AsCoroutine(this Task task)
{
yield return task.AsCoroutineInstruction();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (bug_risk): Consider adding a null check for the Task parameter to fail fast with a clearer exception.

As a public extension method, this can now be invoked on a null Task, leading to a NullReferenceException from task.AsCoroutineInstruction(). Adding a null guard (e.g., throw ArgumentNullException) would give a clearer error and match common extension-method conventions.

- 将AsCoroutine方法重命名为ToCoroutineEnumerator以提高语义清晰度
- 修改StartTaskAsCoroutine方法内部调用改为使用新的ToCoroutineEnumerator方法
- 为ToCoroutineEnumerator方法添加完整的XML文档注释
- 为泛型版本的ToCoroutineEnumerator<T>方法添加类型参数和参数说明
- 统一方法命名规范,提高代码可读性
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant