heii22 2024-06-12 12:50 采纳率: 66.7%
浏览 2
已结题

Unity的Async API和开线程的异步方法有什么区别?

像Unity的Async函数和普通的异步函数有什么区别? 会在什么时候调用?内部使用的是协程吗?

例如我使用Addressables.LoadAssetsAsync,假如我在Update里的第一帧调用了一次,这个时候它会怎么加载?

假如我第三帧又调用了一次 但是这个时候资源还没加载完成 我就添加了一个Completed监听函数 如果在添加的过程中 资源加载好了 就会造成代码逻辑上的错误

例如我进入If(AsyncOperationHandler.isDone)判断后的语句块时 它还没有完成 但是我判断完之后 加载完成了 这个时候再添加监听函数还有用吗 所以Unity Async函数实现的底层逻辑是什么 我觉得只有协程可以避免这种问题吧

所以Unity的Async和它的生命周期有什么关系?

if (resDic.ContainsKey(keyName))
{
    handle = resDic[keyName].handle.Convert<IList<T>>();
    resDic[keyName].count += 1;
    if (handle.IsDone)
    {
        foreach (T item in handle.Result)
            callBack(item);
    }
    else
    {
        handle.Completed += (obj) =>
        {
            if(obj.Status == AsyncOperationStatus.Succeeded)
            {
                foreach (T item in handle.Result)
            }
        };
    }
    return;
}
handle = Addressables.LoadAssetsAsync<T>(list, callBack, mode);
handle.Completed += (obj) =>
{
    if(obj.Status == AsyncOperationStatus.Failed)
    {
        Debug.LogError("资源加载失败" + keyName);
        if (resDic.ContainsKey(keyName))
            resDic.Remove(keyName);
    }
};
AddressablesInfo info = new AddressablesInfo(handle);
resDic.Add(keyName, info);
  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2024-06-12 12:50
    关注

    以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


    Unity的Async API与传统的异步方法(例如使用ThreadTask的异步编程)有几个关键的区别。以下是一些主要的不同点,以及Unity中Async API的使用场景和生命周期的相关信息:

    1. 主线程执行:Unity的Async API,如Addressables.LoadAssetsAsync,是在主线程上执行的,而不是在后台线程。这与.NET中的async/await不同,后者通常在后台线程上执行操作。Unity的API设计为与Unity的主线程同步,以避免多线程访问Unity API时的线程安全问题[^2^][^8^]。

    2. 协程的替代:Unity的Async API可以看作是协程的一种替代。传统上,Unity使用协程来处理异步操作,如加载资源或网络请求。然而,协程不能返回值,且错误处理较为困难。Async API允许使用await关键字等待异步操作完成,同时保持代码的组织性和可读性[^2^][^9^]。

    3. 生命周期和调用时机:Unity的Async API与Unity的生命周期紧密集成。例如,Addressables.LoadAssetsAsync可以在任何需要加载资源的地方调用,包括Update方法。但是,重要的是要注意,由于Unity的单线程特性,异步操作的回调(如Completed事件)将在主线程上执行,这可能会影响性能,尤其是在帧率较高的应用中[^2^][^8^]。

    4. 避免逻辑错误:为了避免在资源加载过程中由于异步操作导致的逻辑错误,重要的是要正确处理异步操作的状态。例如,检查异步操作是否已完成(IsDone),并在添加回调之前确保操作尚未完成。此外,使用async/await可以简化错误处理和状态管理[^2^][^9^]。

    5. 底层实现逻辑:Unity的Async API的底层实现逻辑通常涉及使用AsyncOperationTask来管理异步操作。这些操作在内部使用事件和回调来通知调用者异步操作的状态变化。与协程相比,Async API提供了一种更现代的异步编程模型,允许更细粒度的控制和错误处理[^2^][^9^]。

    6. 代码实现:在提供的代码示例中,handle变量用于跟踪异步操作的状态。通过检查handle.IsDone,可以确定操作是否已经完成。如果操作尚未完成,则可以添加Completed事件的回调来处理加载完成后的逻辑。重要的是要注意,Completed事件的回调将在操作实际完成后触发,无论它是在添加回调之前还是之后完成的。

    7. 参考资料:以下是一些关于Unity Async API和Addressables的参考资料:

    通过这些资料,你可以更深入地了解Unity的Async API,以及如何在Unity项目中有效地使用它们。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月20日
  • 已采纳回答 6月12日
  • 创建了问题 6月12日

悬赏问题

  • ¥15 无源定位系统的时差估计误差标准差
  • ¥15 请问这个代码哪里有问题啊
  • ¥20 python--version在命令端输入结果Python is not defined怎么办?还有pip不是exe格式是不是没安装成功?
  • ¥15 通过GaussianView进行结构微调消除虚频
  • ¥15 调用transformers库
  • ¥15 由于导出的数据名字中带有/,导致Matlab打不开,怎么办?
  • ¥15 新硬盘安装的程序总是崩溃,提示遇到错误
  • ¥15 openpcdet自制数据集评估bev精度和3d精度相同
  • ¥15 excel 上下按钮 显示行
  • ¥20 云卓h12pro 数传问题