using System; using System.Threading; using Cysharp.Threading.Tasks; using GameFramework.Event; namespace SepCore.AsyncTask { /// /// 异步任务辅助类,用于将事件回调转换为 UniTask /// public static class AsyncTaskHelper { /// /// 等待指定事件触发 /// /// 事件参数类型 /// 事件ID /// 事件过滤条件 /// 超时时间(秒),0表示不超时 /// 事件参数 public static UniTask WaitEventAsync(int eventId, Func predicate = null, float timeout = 0f) where T : GameEventArgs { var tcs = new UniTaskCompletionSource(); var eventComponent = global::GameEntry.Event; EventHandler handler = null; handler = (_, e) => { var args = e as T; if (args == null) return; if (predicate != null && !predicate(args)) return; eventComponent.Unsubscribe(eventId, handler); tcs.TrySetResult(args); }; eventComponent.Subscribe(eventId, handler); // 超时处理 if (timeout > 0f) { UniTask.Delay(TimeSpan.FromSeconds(timeout), cancellationToken: CancellationToken.None) .ContinueWith(() => { if (tcs.TrySetException(new TimeoutException($"等待事件超时: {timeout}秒"))) { eventComponent.Unsubscribe(eventId, handler); } }); } return tcs.Task; } /// /// 等待成功或失败事件 /// /// 成功事件参数类型 /// 失败事件参数类型 /// 成功事件ID /// 失败事件ID /// 成功事件过滤条件 /// 失败事件过滤条件 /// 超时时间(秒),0表示不超时 /// 成功事件参数 public static UniTask WaitSuccessOrFailureAsync( int successEventId, int failureEventId, Func successPredicate = null, Func failurePredicate = null, float timeout = 0f) where TSuccess : GameEventArgs where TFailure : GameEventArgs { var tcs = new UniTaskCompletionSource(); var eventComponent = global::GameEntry.Event; // 先声明两个 handler,再赋值 lambda,避免前向引用 EventHandler successHandler = null; EventHandler failureHandler = null; successHandler = (_, e) => { var args = e as TSuccess; if (args == null) return; if (successPredicate != null && !successPredicate(args)) return; eventComponent.Unsubscribe(successEventId, successHandler); eventComponent.Unsubscribe(failureEventId, failureHandler); tcs.TrySetResult(args); }; failureHandler = (_, e) => { var args = e as TFailure; if (args == null) return; if (failurePredicate != null && !failurePredicate(args)) return; eventComponent.Unsubscribe(successEventId, successHandler); eventComponent.Unsubscribe(failureEventId, failureHandler); tcs.TrySetException(new Exception($"操作失败: {args}")); }; eventComponent.Subscribe(successEventId, successHandler); eventComponent.Subscribe(failureEventId, failureHandler); // 超时处理 if (timeout > 0f) { UniTask.Delay(TimeSpan.FromSeconds(timeout), cancellationToken: CancellationToken.None) .ContinueWith(() => { if (tcs.TrySetException(new TimeoutException($"等待事件超时: {timeout}秒"))) { eventComponent.Unsubscribe(successEventId, successHandler); eventComponent.Unsubscribe(failureEventId, failureHandler); } }); } return tcs.Task; } } }