#if !DISABLE_PLAYFABCLIENT_API using System; using System.Collections.Generic; using System.Threading.Tasks; using PlayFab; using PlayFab.ClientModels; using UnityEngine; namespace asap.playfab.async { /// /// 为 PlayFabClientInstanceAPI 提供异步 Task 封装及通用重试能力的扩展方法。 /// public static class PlayFabClientInstanceAsyncExtensions { /// /// 将 PlayFabClientInstanceAPI 的回调式方法转换为 Task,可与 ExecuteWithRetryAsync 配合使用。 /// /// /// var result = await api.ExecuteWithRetryAsync( /// () => api.ToAsync(request, api.LoginWithCustomID) /// ); /// public static Task ToAsync( this PlayFabClientInstanceAPI api, TRequest request, Action, Action, object, Dictionary> apiMethod) where TResult : class { var task = new TaskCompletionSource(); apiMethod( request, result => task.SetResult(result), error => { Debug.LogError(error.GenerateErrorReport()); task.SetResult(null); }, null, null); return task.Task; } /// /// 通用重试封装,将任意返回 Task<T> 的调用包裹在重试逻辑中。 /// 当调用返回 null(即发生错误)时触发重试,采用指数退避策略。 /// /// API 返回结果类型 /// PlayFabClientInstanceAPI 实例 /// 要执行的调用,形如 () => api.ToAsync(request, api.XxxMethod) /// 最大重试次数,默认 3 次 /// 首次重试等待秒数,每次重试翻倍(指数退避),默认 1 秒 /// 成功时返回结果对象,所有重试均失败后返回 null public static async Task ExecuteWithRetryAsync( this PlayFabClientInstanceAPI api, Func> apiCall, int maxRetries = 3, float retryDelaySeconds = 1f) where T : class { var attempts = 0; while (true) { var result = await apiCall(); if (result != null) return result; if (attempts >= maxRetries) { Debug.LogWarning($"[PlayFabRetry] 已达到最大重试次数 {maxRetries},放弃重试。"); return null; } var delaySeconds = retryDelaySeconds * Mathf.Pow(2f, attempts); Debug.LogWarning($"[PlayFabRetry] 第 {attempts + 1} 次重试,等待 {delaySeconds:F1} 秒后重试..."); await Task.Delay(TimeSpan.FromSeconds(delaySeconds)); attempts++; } } } } #endif