Unity中如何将协程写法重构为Async/Await异步实现?
Unity协程转Async/Await异步写法重构方案
一、重构核心API方法
将原协程方法改为返回Task<string>的异步方法,移除回调参数,用using自动释放资源,让代码逻辑更线性:
using UnityEngine; using UnityEngine.Networking; using System.Threading.Tasks; public async Task<string> GetCompletionAsync(string prompt, float temperature = 0.8f) { // 使用using自动释放UnityWebRequest,无需手动调用Dispose using (UnityWebRequest www = UnityWebRequest.Post("https://api.openai.com/v1/completions", "")) { // 补充原代码中省略的请求配置(示例) www.SetRequestHeader("Content-Type", "application/json"); www.SetRequestHeader("Authorization", "Bearer YOUR_API_KEY"); // 构造请求体(根据OpenAI API要求序列化参数) var requestBody = JsonUtility.ToJson(new { model = "text-davinci-003", prompt = prompt, temperature = temperature, max_tokens = 100 }); www.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(requestBody)); // 异步等待请求完成 await www.SendWebRequest(); // 错误处理 if (www.result is UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError) { Debug.LogError($"请求错误:{www.error}"); throw new System.Exception(www.error); // 抛出异常让调用方捕获处理 } // 解析并返回结果 return GetResultFromJson(www.downloadHandler.text); } } // 保留原有的JSON解析方法 private string GetResultFromJson(string jsonText) { // 原解析逻辑示例 var response = JsonUtility.FromJson<CompletionResponse>(jsonText); return response.choices[0].text; } // 用于JSON解析的模型类(示例) [System.Serializable] private class CompletionResponse { public Choice[] choices; } [System.Serializable] private class Choice { public string text; }
二、简化调用逻辑
调用时直接用await替代StartCoroutine,结合try/catch处理异常,代码无嵌套更易读:
// 在MonoBehaviour类中定义异步调用方法 async void FetchAndLogCompletion() { const string prompt = "Albert Einstein was"; try { // 直接await获取结果,无需回调 string result = await textAI.GetCompletionAsync(prompt, temperature: 0.5f); Debug.Log(result); } catch (System.Exception ex) { Debug.LogError($"获取结果失败:{ex.Message}"); } } // 启动调用(例如在Start方法中) void Start() { FetchAndLogCompletion(); }
三、多任务并行处理示例
利用Task.WhenAll可轻松实现多个异步请求并行等待,满足多任务场景需求:
async void FetchMultipleCompletions() { var prompts = new string[] { "Albert Einstein was", "Marie Curie was", "Nikola Tesla was" }; // 创建所有异步任务 var completionTasks = prompts.Select(p => textAI.GetCompletionAsync(p, 0.5f)).ToList(); // 等待所有任务完成,一次性获取所有结果 string[] results = await Task.WhenAll(completionTasks); // 遍历处理结果 for (int i = 0; i < results.Length; i++) { Debug.Log($"[{prompts[i]}] 的结果:\n{results[i]}"); } }
关键注意事项
- Unity版本要求:建议使用Unity 2020.3及以上版本,对Async/Await的支持更完善
- MonoBehaviour异步方法:UI交互、生命周期触发的异步方法用
async void,其他工具类方法优先用async Task - 异常处理:通过
try/catch统一捕获错误,比原回调式错误处理更集中直观 - 资源释放:
using语句自动管理UnityWebRequest的生命周期,避免资源泄漏
内容的提问来源于stack exchange,提问作者Philipp Lenssen
相关产品推荐
相关产品推荐

