From b196cd40bb7463b53f28a8859b172c8f4ea2e583 Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Mon, 16 Feb 2026 22:04:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(coroutine):=20=E6=B7=BB=E5=8A=A0Mediator?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E4=B8=8E=E5=8D=8F=E7=A8=8B=E9=9B=86=E6=88=90?= =?UTF-8?q?=E7=9A=84=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现SendCommandCoroutine方法,支持以协程方式发送命令并处理异常 - 实现SendCommandAndWaitEventCoroutine方法,支持发送命令并等待特定事件 - 添加超时控制功能,支持设置等待事件的超时间 - 集成IEventBus和IMediator服务,提供完整的事件驱动协程支持 - 提供异常回调处理机制,增强错误处理能力 - 实现资源清理机制,确保WaitForEvent对象正确释放 --- .../extensions/MediatorCoroutineExtensions.cs | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 GFramework.Core/coroutine/extensions/MediatorCoroutineExtensions.cs diff --git a/GFramework.Core/coroutine/extensions/MediatorCoroutineExtensions.cs b/GFramework.Core/coroutine/extensions/MediatorCoroutineExtensions.cs new file mode 100644 index 0000000..046964f --- /dev/null +++ b/GFramework.Core/coroutine/extensions/MediatorCoroutineExtensions.cs @@ -0,0 +1,108 @@ +// 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 +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using GFramework.Core.Abstractions.coroutine; +using GFramework.Core.Abstractions.events; +using GFramework.Core.Abstractions.rule; +using GFramework.Core.coroutine.instructions; +using Mediator; + +namespace GFramework.Core.coroutine.extensions; + +/// +/// 提供Mediator模式与协程集成的扩展方法。 +/// 包含发送命令和等待事件的协程实现。 +/// +public static class MediatorCoroutineExtensions +{ + /// + /// 以协程方式发送命令并处理可能的异常。 + /// + /// 命令的类型 + /// 上下文感知对象,用于获取服务 + /// 要发送的命令对象 + /// 发生异常时的回调处理函数 + /// 协程枚举器,用于协程执行 + public static IEnumerator SendCommandCoroutine( + this IContextAware contextAware, + TCommand command, + Action? onError = null) + where TCommand : notnull + { + var mediator = contextAware + .GetContext() + .GetService()!; + + var task = mediator.Send(command).AsTask(); + + yield return task.AsCoroutineInstruction(); + + if (task.IsFaulted) + onError?.Invoke(task.Exception!); + } + + /// + /// 发送命令并等待特定事件的协程实现,支持超时控制。 + /// + /// 命令的类型 + /// 要等待的事件类型 + /// 上下文感知对象,用于获取服务 + /// 要发送的命令对象 + /// 接收到事件时的回调处理函数 + /// 超时时间(秒),0表示无超时 + /// 协程枚举器,用于协程执行 + public static IEnumerator SendCommandAndWaitEventCoroutine( + this IContextAware contextAware, + TCommand command, + Action? onEvent = null, + float timeout = 0f) + where TCommand : notnull + where TEvent : class + { + var context = contextAware.GetContext(); + var mediator = context.GetService()!; + var eventBus = context.GetService()!; + + WaitForEvent? wait = null; + + try + { + wait = new WaitForEvent(eventBus); + + var task = mediator.Send(command).AsTask(); + + yield return task.AsCoroutineInstruction(); + + if (timeout > 0f) + { + var timeoutWait = new WaitForEventWithTimeout(wait, timeout); + yield return timeoutWait; + + if (timeoutWait.IsTimeout) + throw new TimeoutException( + $"wait for event {typeof(TEvent).Name} timeout."); + } + else + { + yield return wait; + } + + if (wait.EventData != null) + onEvent?.Invoke(wait.EventData); + } + finally + { + wait?.Dispose(); + } + } +} \ No newline at end of file