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

如何对AssetBundle.LoadAssetAsync使用await?非Task类型如何支持await?

Unity中非Task类型异步操作的await实现方案

C# 的 await 关键字并非只能作用于 Task/Task<T> 类型,只要目标类型符合可等待模式:即提供返回符合规范的 awaiter 对象的 GetAwaiter() 方法,就可以被 await 修饰。你代码中的 AssetBundleRequest 属于 Unity 异步操作基类 AsyncOperation 的子类,适配方案如下:

方案1:直接使用Unity官方内置支持

Unity 2018.1 及以上版本默认已经为所有 AsyncOperation 类型(包括AssetBundleRequest、ResourceRequest、场景加载异步句柄等)实现了 GetAwaiter 扩展,只要你满足以下两个条件,你标注//that's wrong的代码其实可以直接正常运行:

  • 项目脚本运行时版本设置为 .NET 4.x Equivalent 或更高
  • 代码文件引用了 UnityEngine 命名空间

方案2:自定义扩展适配低版本/旧运行时

如果你的项目使用的Unity版本低于2018.1,或是仍在使用.NET 3.5兼容运行时,可以自行实现AsyncOperation的可等待扩展,代码如下:

using System.Runtime.CompilerServices;
using UnityEngine;
using System.Threading.Tasks;

public static class AsyncOperationAwaiterExtension
{
    // 适配所有AsyncOperation基础类型的扩展
    public static TaskAwaiter GetAwaiter(this AsyncOperation asyncOp)
    {
        var tcs = new TaskCompletionSource<object>();
        asyncOp.completed += _ => tcs.SetResult(null);
        return ((Task)tcs.Task).GetAwaiter();
    }

    // 适配AssetBundleRequest带返回结果的泛型扩展
    public static TaskAwaiter<AssetBundleRequest> GetAwaiter(this AssetBundleRequest asyncOp)
    {
        var tcs = new TaskCompletionSource<AssetBundleRequest>();
        asyncOp.completed += _ => tcs.SetResult(asyncOp);
        return tcs.Task.GetAwaiter();
    }
}

添加完上述扩展后,你原有代码不需要做任何修改,await req就可以正常执行,等待资源加载完成后才会执行后续逻辑。

修正后的完整代码示例

Task<AssetBundle> request = assetbundles.LoadBundleAsync(bundleName); 
await request;
AssetBundleRequest req = request.Result.LoadAssetAsync<T>(assetPath);
await req; // 增加扩展后可以正常工作
return req.asset as T;

注:Unity中的异步操作await完成后默认会回到Unity主线程,不需要额外处理线程上下文切换问题


内容的提问来源于stack exchange,提问作者xcom2000

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:39:03