From 855b3f9eac7d3f7f446c4da8db39cc79034f66c9 Mon Sep 17 00:00:00 2001
From: GeWuYou <95328647+GeWuYou@users.noreply.github.com>
Date: Mon, 16 Feb 2026 22:19:12 +0800
Subject: [PATCH] =?UTF-8?q?refactor(coroutine):=20=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E5=8D=8F=E7=A8=8B=E6=89=A9=E5=B1=95=E4=B8=AD=E7=9A=84=E5=BC=82?=
=?UTF-8?q?=E5=B8=B8=E5=A4=84=E7=90=86=E5=92=8C=E5=8F=82=E6=95=B0=E9=AA=8C?=
=?UTF-8?q?=E8=AF=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 修改了CommandCoroutineExtensions和MediatorCoroutineExtensions中的异常处理逻辑
- 添加了对负数超时参数的验证和异常抛出
- 改进了服务获取的空值检查机制
- 更新了文档注释以提供更清晰的参数说明
- 重构了SendCommandAndWaitEvent方法的实现结构
- 统一了错误消息格式和异常处理方式
---
.../extensions/CommandCoroutineExtensions.cs | 63 ++++++++++----
.../extensions/MediatorCoroutineExtensions.cs | 85 +++++++++++++++----
2 files changed, 117 insertions(+), 31 deletions(-)
diff --git a/GFramework.Core/coroutine/extensions/CommandCoroutineExtensions.cs b/GFramework.Core/coroutine/extensions/CommandCoroutineExtensions.cs
index a919458..62183ca 100644
--- a/GFramework.Core/coroutine/extensions/CommandCoroutineExtensions.cs
+++ b/GFramework.Core/coroutine/extensions/CommandCoroutineExtensions.cs
@@ -43,19 +43,30 @@ public static class CommandCoroutineExtensions
yield return task.AsCoroutineInstruction();
- if (task.IsFaulted) onError?.Invoke(task.Exception!);
+ if (!task.IsFaulted) yield break;
+ if (onError != null)
+ onError.Invoke(task.Exception!);
+ else
+ throw task.Exception!.InnerException ?? task.Exception;
}
///
- /// 发送 Command 并等待指定 Event
+ /// 发送 Command 并等待指定 Event。
///
- /// 命令类型,必须实现 IAsyncCommand 接口
+ /// 命令类型,必须实现 IAsyncCommand
/// 事件类型
/// 上下文感知对象
/// 要执行的命令实例
/// 事件触发时的回调处理
- /// 等待超时时间(秒),0表示无限等待
- /// 返回协程指令枚举器
+ ///
+ /// 超时时间(秒):
+ ///
+ /// - timeout < 0: 无效,将抛出 ArgumentOutOfRangeException
+ /// - timeout == 0: 无超时,永久等待
+ /// - timeout > 0: 启用超时机制
+ ///
+ ///
+ /// 当 timeout 小于 0 时抛出。
public static IEnumerator SendCommandAndWaitEventCoroutine(
this IContextAware contextAware,
TCommand command,
@@ -63,44 +74,64 @@ public static class CommandCoroutineExtensions
float timeout = 0f)
where TCommand : IAsyncCommand
where TEvent : class
+ {
+ // 参数检查部分
+ if (timeout < 0f)
+ throw new ArgumentOutOfRangeException(
+ nameof(timeout),
+ timeout,
+ "Timeout must be greater than or equal to 0.");
+
+ // 迭代器逻辑部分
+ return SendCommandAndWaitEventIterator(contextAware, command, onEvent, timeout);
+ }
+
+ ///
+ /// 发送 Command 并等待指定 Event 的迭代器实现。
+ ///
+ private static IEnumerator SendCommandAndWaitEventIterator(
+ IContextAware contextAware,
+ TCommand command,
+ Action? onEvent,
+ float timeout)
+ where TCommand : IAsyncCommand
+ where TEvent : class
{
var context = contextAware.GetContext();
- var eventBus = context.GetService()!;
+ var eventBus = context.GetService()
+ ?? throw new InvalidOperationException("IEventBus not found.");
WaitForEvent? wait = null;
try
{
- // 先注册事件监听器
+ // 先注册事件监听
wait = new WaitForEvent(eventBus);
- // 发送异步命令并等待完成
+ // 发送命令
var task = context.SendCommandAsync(command);
yield return task.AsCoroutineInstruction();
- // 如果有超时设置,使用超时等待
+ // 等待事件
if (timeout > 0f)
{
var timeoutWait = new WaitForEventWithTimeout(wait, timeout);
yield return timeoutWait;
- // 检查是否超时
if (timeoutWait.IsTimeout)
- // 超时处理
- throw new TimeoutException($"wait for the event ${typeof(TEvent).Name} timeout.");
+ throw new TimeoutException(
+ $"Wait for event {typeof(TEvent).Name} timeout.");
}
else
{
- // 等待事件触发(无超时)
yield return wait;
}
- // 调用事件回调
- if (onEvent != null && wait.EventData != null) onEvent.Invoke(wait.EventData);
+ if (wait.EventData != null)
+ onEvent?.Invoke(wait.EventData);
}
finally
{
- // 确保清理事件监听器
wait?.Dispose();
}
}
diff --git a/GFramework.Core/coroutine/extensions/MediatorCoroutineExtensions.cs b/GFramework.Core/coroutine/extensions/MediatorCoroutineExtensions.cs
index 046964f..edbf02a 100644
--- a/GFramework.Core/coroutine/extensions/MediatorCoroutineExtensions.cs
+++ b/GFramework.Core/coroutine/extensions/MediatorCoroutineExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2026 GeWuYou
+// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -47,20 +47,31 @@ public static class MediatorCoroutineExtensions
yield return task.AsCoroutineInstruction();
- if (task.IsFaulted)
- onError?.Invoke(task.Exception!);
+ if (!task.IsFaulted) yield break;
+ if (onError != null)
+ onError.Invoke(task.Exception!);
+ else
+ throw task.Exception!.InnerException ?? task.Exception;
}
+ // ... existing code ...
///
- /// 发送命令并等待特定事件的协程实现,支持超时控制。
+ /// 发送命令并等待特定事件的协程实现。
///
- /// 命令的类型
+ /// 命令类型
/// 要等待的事件类型
- /// 上下文感知对象,用于获取服务
- /// 要发送的命令对象
- /// 接收到事件时的回调处理函数
- /// 超时时间(秒),0表示无超时
- /// 协程枚举器,用于协程执行
+ /// 上下文对象
+ /// 要发送的命令
+ /// 事件触发时的回调
+ ///
+ /// 超时时间(秒):
+ ///
+ /// - timeout < 0: 无效,将抛出 ArgumentOutOfRangeException
+ /// - timeout == 0: 无超时,永久等待
+ /// - timeout > 0: 启用超时机制
+ ///
+ ///
+ /// 当 timeout 小于 0 时抛出。
public static IEnumerator SendCommandAndWaitEventCoroutine(
this IContextAware contextAware,
TCommand command,
@@ -69,10 +80,54 @@ public static class MediatorCoroutineExtensions
where TCommand : notnull
where TEvent : class
{
- var context = contextAware.GetContext();
- var mediator = context.GetService()!;
- var eventBus = context.GetService()!;
+ // 参数验证
+ ValidateParameters(timeout);
+ // 获取必要的服务
+ var context = contextAware.GetContext();
+ var mediator = context.GetService()
+ ?? throw new InvalidOperationException("IMediator not found.");
+ var eventBus = context.GetService()
+ ?? throw new InvalidOperationException("IEventBus not found.");
+
+ // 执行协程逻辑
+ return ExecuteSendCommandAndWaitEventCoroutine(mediator, eventBus, command, onEvent, timeout);
+ }
+
+ ///
+ /// 验证方法参数的有效性。
+ ///
+ /// 超时时间
+ /// 当 timeout 小于 0 时抛出。
+ private static void ValidateParameters(float timeout)
+ {
+ if (timeout < 0f)
+ throw new ArgumentOutOfRangeException(
+ nameof(timeout),
+ timeout,
+ "Timeout must be greater than or equal to 0.");
+ }
+
+ ///
+ /// 执行发送命令并等待事件的协程逻辑。
+ ///
+ /// 命令类型
+ /// 事件类型
+ /// 中介者服务
+ /// 事件总线服务
+ /// 要发送的命令
+ /// 事件回调
+ /// 超时时间
+ /// 协程枚举器
+ private static IEnumerator ExecuteSendCommandAndWaitEventCoroutine(
+ IMediator mediator,
+ IEventBus eventBus,
+ TCommand command,
+ Action? onEvent,
+ float timeout)
+ where TCommand : notnull
+ where TEvent : class
+ {
WaitForEvent? wait = null;
try
@@ -80,7 +135,6 @@ public static class MediatorCoroutineExtensions
wait = new WaitForEvent(eventBus);
var task = mediator.Send(command).AsTask();
-
yield return task.AsCoroutineInstruction();
if (timeout > 0f)
@@ -90,7 +144,7 @@ public static class MediatorCoroutineExtensions
if (timeoutWait.IsTimeout)
throw new TimeoutException(
- $"wait for event {typeof(TEvent).Name} timeout.");
+ $"Wait for event {typeof(TEvent).Name} timeout.");
}
else
{
@@ -105,4 +159,5 @@ public static class MediatorCoroutineExtensions
wait?.Dispose();
}
}
+// ... existing code ...
}
\ No newline at end of file