对应的形象区别:
一个简单的例子
等待5秒输出Log
Coroutine:
1 2 3 4 5 6 7 8 9 10 11 |
private void Start() { StartCoroutine(WaitCoroutine(5, () => Debug.Log("Coroutine Finished"))); } private IEnumerator WaitCoroutine(float time, Action method) { yield return new WaitForSeconds(time); //you code: method?.Invoke(); } |
async / await
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using System; using System.Threading.Tasks; private void Start() { //StartCoroutine(WaitCoroutine(5, () => Debug.Log("Coroutine Finished"))); WaitTask(5, () => Debug.Log("Task Finished")); } private async void WaitTask(float time, Action method) { float startTime = Time.time; float currentTime = startTime; while (currentTime - startTime < time) { currentTime += Time.deltaTime; await Task.Yield(); } method?.Invoke(); } |
简评:感觉差不多,甚至好像await实现方式还要复杂一点?
扩展应用:一个复杂的例子
要求绕Z轴旋转2圈并且向右以2米/s的速度移动5秒后,原地停止1秒,向上移动5米并且缩小到一半大小,共2秒,然后输入Log
Coroutine: ???
async / await
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
private async void BeginTest() { List<Task> tasks = new List<Task>(); var from = transform.localEulerAngles; var to = from; to.z += 720; var act1 = TimeCount(5, (c, s) => { transform.localEulerAngles = Vector3.Lerp(from, to, c / s); transform.position += new Vector3(2, 0, 0) * Time.deltaTime; }); tasks.Add(act1); tasks.Add(TimeCount(1)); from = transform.localScale; to = from / 2; var pos = transform.position; var toPos = pos; toPos.y += 5; var act3 = TimeCount(2, (c, s) => { transform.localScale = Vector3.Lerp(from, to, c / s); transform.position = Vector3.Lerp(pos, toPos, c / s); }); tasks.Add(act3); await Task.WhenAll(tasks); Debug.Log("Finished!"); } private async Task TimeCount(float time, Action<float, float> method = null) { float startTime = Time.time; float currentTime = startTime; while (currentTime - startTime < time) { currentTime += Time.deltaTime; method?.Invoke(currentTime - startTime, time); await Task.Yield(); } } |
简评:await 香。
很香.