Async/Await學習筆記
1. Coroutine不能回傳值;Async/Await可以
public class CoroutineSample : MonoBehaviour
{
private void Start()
{
StartCoroutine(routine());
}
private IEnumerator routine()
{
yield return null;
}
}
public class AsyncReturnValue : MonoBehaviour
{
private async void Start()
{
int result = await GetCount();
}
private async Task<int> GetCount()
{
return await Task.FromResult<int>(1);
}
}
2. Coroutine每偵一次循環;Async/Await同步執行
public class CoroutineFrame : MonoBehaviour
{
private void Start()
{
StartCoroutine(Routine());
}
private IEnumerator Routine()
{
Debug.Log($"Frame: {Time.frameCount}");
yield return null;
Debug.Log($"Frame: {Time.frameCount}");
}
//Outputs:
//Frame:1
//Frame:2
}
public class AsyncFrame : MonoBehaviour
{
private async void Start()
{
Debug.Log($"Frame: {Time.frameCount}");
await Function();
Debug.Log($"Frame: {Time.frameCount}");
}
private async Task Function()
{
await Task.Yield();
}
//Outputs:
//Frame:1
//Frame:1
}
3. Coroutine依賴於Monobehaviour;Async/Await為C#語法
4. Coroutine不支援try/catch;Async/Await支援
5. Coroutine依賴的Monobehaviour被移除將停止執行可能造成記憶體未釋放;Async/Await會照常執行
public class CoroutineLeak : MonoBehaviour
{
private IEnumerator ShowTexture(RawImage container)
{
var texture = new RenderTexture(512, 512, 0);
container.texture = texture;
for(int i = 0; i < 100; ++i)
{
yield return null;
}
//迴圈結束前MonoBehaviour被刪除將不會執行
texture.Release();
}
}
public class AsyncLeak : MonoBehaviour
{
async Task ShowTexture(RawImage container)
{
var texture = new RenderTexture(512, 512, 0);
container.texture = texture;
for (int i = 0; i < 100; ++i)
await Task.Yield();
//不會因MonoBehaviour被刪除而停止執行
texture.Release();
}
}
6. Async/Await提供較為詳細的Call Stack
7. Coroutine生命週期依賴於Monobehaviour;Async/Await則較靈活
8. 針對I/O-bound code使用Task或Task<T>等不需建立thread的方法;CPU-bound則使用Task.Run等方法建立背景執行緒做CPU運算
Reference: