I am using UniTask in Unity 2020.3. And I want to call an async method which returns a UniTask in Unity Event Function.
For some reason, I cannot change the event function to async version, is there any other way to call it?
Such as, wrap the async method into a callback function?
For example, I have an async function like this:
public void async UniTask<string> GetStringAsync();
And I want to call it like below:
public class MyMonoBehaviour: MonoBehaviour
{
pirvate string myString;
pirvate void Start()
{
myString = await GetStringAsync();
}
}
I cannot use await in Start()
because it is not an async function.
So, I want to wrap GetStringAsync()
into a callback function and call it in Start()
, but I have no idea how to do it.
I know the simplest solution is to change Start()
to async Start()
,
But what if I want to call GetStringAsync()
in any normal function? Change it to async again?
I dislike the async
spread in my code base like virus. Because the function may be some legacy code, I want to modify it as little as possible.
CodePudding user response:
I would solve this by changing the signature to async void Start()
. That works. If you need Update
to be delayed until Start
finishes, change Start
to a coroutine and use UniTask's API for creating an iterator from a task (which you will yield).
Note: I don't use the UniTask
library, but it seems pretty equivalent to Async Await Utils
. Both provide the GetAwaiter()
extension method for common Unity types. There is certainly some function that lets a coroutine wait for a task (by wrapping it in an IEnumerator
).
CodePudding user response:
I found the solution I wanted for myself.
I create a wrapper function like below:
public void async UniTask<string> GetStringCallbackAsync(Action<string> onDone) {
string result = await GetStringAsync();
onDone(result);
}
And I can call it in any function like below:
GetStringCallbackAsync(result => {
Debug.log($"result = {result}");
}
).Forget();
Maybe I didn't describe my question clearly, but this is the result I wanted.