16.总结
16.1 核心要点速览
安装UniTask
- 指定版本:在链接后附加版本标签,如
https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask#2.1.0
- 手动编辑:在
Packages/manifest.json
添加依赖"com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask"
协程、Task与UniTask对比
类型 | 代码结构 | 异常处理 | 性能开销 | 取消支持 | 依赖关系 | 返回值处理 | 适用场景 |
---|---|---|---|---|---|---|---|
协程 | 手动管理生命周期,需继承MonoBehaviour | 需在协程内部捕获异常,无法向上传播 | 每次yield return 产生GC分配(约24字节) |
需自定义取消逻辑,无原生支持 | 依赖MonoBehaviour | 通过回调或共享变量获取 | 简单异步逻辑,如动画过渡、场景加载 |
Task | 异步代码较简洁,支持async/await |
支持全局异常处理器TaskScheduler.UnobservedTaskException |
涉及线程切换和上下文捕获,开销较高 | 原生支持CancellationToken |
依赖.NET线程池 | 通过Task<T> 返回值 |
跨平台异步操作,如文件IO、计算密集型任务 |
UniTask | 异步代码扁平化,更直观 | 支持全局异常处理器UniTaskScheduler.UnobservedTaskException |
零GC分配(基于值类型和对象池) | 原生支持CancellationToken ,可结合GetCancellationTokenOnDestroy |
基于Unity的PlayerLoop,不依赖线程 | 通过UniTask<T> 返回值 |
Unity内异步操作,如UI事件、资源加载、网络请求 |
常见API
分类 | 详情 |
---|---|
优势 | 解决协程依赖Monobehaviour 、无法异常处理、难获取返回值问题 |
延时操作 | Delay /DelayFrame :按时间/帧数延时Yield :等待一帧(可指定PlayerLoopTiming 阶段)NextFrame :等待下一帧渲染完成WaitForEndOfFrame :等待帧结束 |
等待操作 | WaitUntil :等待条件满足WaitUntilValueChanged :等待值变化 |
条件操作 | WhenAll :等待所有任务完成WhenAny :等待任一任务完成 |
异步委托 | UniTask.Void :即发即弃操作UniTask.Defer :延迟执行异步操作UniTask.Lazy :支持多次await ,内部逻辑仅执行一次 |
异常处理 | Try Catch :捕获异常SuppressCancellationThrow :返回(bool IsCanceled, T Result) 避免抛出异常 |
补充对比 | Forget() :消除未await 警告async UniTaskVoid 优于async void ,避免线程资源浪费 |
UniTask与协程转换 | 直接await 协程:简化代码并处理结果协程转 UniTask :coroutine.ToUniTask(this) UniTask 转协程:UniTask.Delay().ToCoroutine() |
资源异步加载 | 原生协程:轮询状态、手动管理生命周期、有GC分配、代码嵌套 UniTask:代码简洁、性能优化(零GC分配) |
超时处理 | SuppressCancellationThrow :返回取消状态避免异常TimeoutController :复用令牌减少堆内存分配 |
请求网络图片 | 优先用UniTask ,避免async void ,添加CancellationToken |
UI监听 | 异步LINQ监听:如btn.OnClickAsAsyncEnumerable().Take(3).ForEachAsync 实现三连击检测 |
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com