在之前Unity想要实现延迟执行或者是等待,要么只能使用自己计数的方法,要么使用协程。
Ep.1 协程
首先让我们来看一个协程示例:
示例是循环10次,每次等待0.2s。
协程示例1 2 3 4 5 6 7 8 9 10 11
| IEnumerator Func() { for (int i = 0; i < 10; i++) { print(i); yield return new WaitForSeconds(0.2f); } }
StartCoroutine(Func());
|
Ep.2 Async 异步
Async异步的概念是微软基于多线程提出的Task解决方案,相比传统多线程具有很多优势。
- :heart:相比协程来说,异步的方式不需要搭建基础的协程框架(
不需要新创建一个方法),可以直接在方法中使用关键字实现等待。
- 不需要启动
Async示例1 2 3 4 5 6 7 8
| async void AsyncFunc() { for (int i = 0; i < 10; i++) { print(i); await Task.Delay(100); } }
|
Ep.3 解决痛点
其实async还有其他的优势,让我们来看看这些例子:smiley_cat:
协程队列
:first_quarter_moon: 有时我们需要这样一种情况,需要在A执行结束后执行B,B执行结束后执行C。
协程解决方案
可以看到,通用的解决方案需要创建多个协程方法,并创建一个总协程方法来为所有参与协程进行排序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| IEnumerator FunAll() { yield return FunA(); yield return FunB(); yield return FunC(); print("全部执行结束!"); }
IEnumerator FunA() { yield return new WaitForSeconds(1f); print("A执行结束!"); }
IEnumerator FunB() { yield return new WaitForSeconds(1f); print("B执行结束!"); }
IEnumerator FunC() { yield return new WaitForSeconds(2f); print("C执行结束!"); }
|
异步解决方案
按照协程的思路我们可以这样来替换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| private async void Run() { await Fun1(); await Fun2(); print("FunEnd"); }
private async Task Fun1() { await Task.Delay(2000); print("Fun1"); } private async Task Fun2() { await Task.Delay(2000); print("Fun2"); }
|
特殊使用
持续执行
可以使用如下的方式来持续执行一系列的动作!:smirk:
1 2 3 4 5 6 7 8 9 10 11
| async Task Rote(float endTime, Vector3 dir) { while (Time.time < endTime) { transform.position += dir; await Task.Yield(); }
print("执行完成"); }
|
多任务并行
可以为Start方式设定异步Async
1 2 3 4 5 6 7 8 9 10 11
| private async void Start() { var tasks=new List<Task>(); for (int i = 0; i < 3; i++) { tasks.Add(Fun1()); } await Task.WhenAll(tasks); print("全部执行完"); }
|
Ep.4 总结
使用这样Async方式,大大简化了协程的使用复杂度,简化了代码数量,重要的是可以将一些Task的特性使用出来。
:heavy_check_mark:同时,Unity再也不是虚假的多线程了!