Appearance
异步 async/await
核心理解
async/await 是一种“等待异步任务”的写法。
async Task LoadAsync()
{
Debug.Log("开始加载");
await Task.Delay(1000);
Debug.Log("一秒后继续");
}await 的意思不是卡住整个游戏,而是: 当前 async 方法先暂停,等任务完成后,再从 await 后面继续。
常见返回类型
c
async Task DoAsync()
{
await Task.Delay(1000);
}
async Task<int> GetScoreAsync()
{
await Task.Delay(1000);
return 100;
}Task:异步任务,没有返回值。 Task<T>:异步任务,完成后返回一个 T。 async void:少用,通常只用于 Unity 入口或事件回调。
Unity 里怎么理解
协程更适合时间流程:
c
yield return new WaitForSeconds(1f);async/await 更适合等异步结果:
c
int score = await GetScoreAsync();Unity 6 里还有 Awaitable:
c
async Awaitable DelayAsync()
{
await Awaitable.WaitForSecondsAsync(1f);
Debug.Log("继续");
}它不是线程
async/await 本身不等于开新线程。 如果你写的是网络、文件、引擎异步加载,它可以不堵主流程。 但如果你在 async 方法里写很重的 CPU 计算,它仍然可能卡住主线程。
异常要用 try/catch
c
try
{
await LoadConfigAsync();
}
catch (Exception e)
{
Debug.LogException(e);
}被 await 的任务如果出错,异常会在 await 那一行重新抛出来。
常见坑
不要随便用:
c
task.Wait();
task.Result;它们可能阻塞 Unity 主线程。 也不要忘记 await,否则后续代码可能比异步任务更早执行。 如果异步任务跨到后台线程,回来修改 GameObject、Transform、UI 之前,要确保回到 Unity 主线程。
选择口诀
每帧输入、移动、检测:Update。 延迟、渐变、波次、剧情流程:Coroutine。 网络、文件、SDK、异步加载、等待结果:async/await。 大量 CPU 计算:考虑 Task.Run、Job System、Burst 或分帧处理。
参考链接