You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:01:01