Closed steuraa closed 4 years ago
Generally speaking, you want to perform networking tasks off the main thread. Coroutines achieve this by performing work over time by polling code, but ultimately coroutines were just a workaround for the lack of async/await in the past.
You do not have to use coroutines with this library, but you do need a way to "delegate" results over to code that exists on the main thread if you use async/await. There are many ways to do this, and it will highly depend on your game.
In order to use async/await with Unity code directly: Check out UnityMainThreadDispatcher https://github.com/PimDeWitte/UnityMainThreadDispatcher It is a way to queue up method calls to be executed on the main thread. A very straightforward way to transfer results to the main thread.
In order to use this library with Coroutines, you need to add a CustomYieldInstruction. This is also pretty straightforward:
using System;
using System.Threading.Tasks;
using UnityEngine;
public class WaitForAsync : CustomYieldInstruction
{
private bool _taskDone = false;
public override bool keepWaiting => !_taskDone;
public WaitForAsync(Func<Task> func)
{
RunAsyncFunc(func);
}
private async void RunAsyncFunc(Func<Task> func)
{
await func.Invoke();
_taskDone = true;
}
}
Then, in the Coroutine, you can call:
yield return new WaitForAsync(/*async func*/);
inside the coroutine and it will wait like normal. This shouldn't require dispatching to the main thread since the coroutine handles it.
I will probably add some documentation to the front page if/when I have some free time. I can probably throw in a CustomYieldInstruction as well so one doesn't have to make their own.
Alright, I've pushed a new update (a1bb2adcb9a94e4fd74abd2ca3671c9733a02460) that contains a custom yield instruction for coroutines. More information is on the README in the Coroutines section.
Wow thanks for the detailed response! I'll probably stick to async/await as it's more familiar to me (coming from JS background), but might coming in handy for others and I've learned something new in the process!
In the readme it says that the library is usable with coroutines with callback, would you mind adding an example on how to achieve this for those amongst us with less in depth C# knowledge?
Also, is there a advantage of using coroutines over async/await? I read in the Unity manual that using async/await is discouraged, but don't know how or if this applies to this situation?