When using the UniRx package in Unity, one can use async-await. But what's the right way to convert something like the following (this example uses a GPT-3 www request, but it could be anything)
string result1 = await textAI.GetCompletion("Albeit Einstein was");
string result2 = await textAI.GetCompletion("Susan Sarandon is");
to something that launches the GetCompletion functions simultaneously, then continues when all finished and returned their result? E.g. using pseudo-code, like this:
string result1 = null;
string result2 = null;
await Task.WhenAll({
result1 = await textAI.GetCompletion("Albeit Einstein was"),
result2 = await textAI.GetCompletion("Susan Sarandon is")
});
Debug.Log("Results: " result1 ", " result2);
Thanks!
CodePudding user response:
You could use the existing Task.WhenAll
async void Start()
{
Task<string> a = AsyncRoutineA(); // Here no await, you want the Task object
Task<string> b = AsyncRoutineB();
await Task.WhenAll(a, b); // add all tasks and await that one
Debug.Log(a.Result " " b.Result);
}
async Task<string> AsyncRoutineA()
{
await Task.Delay(1000);
return "A Done";
}
async Task<string> AsyncRoutineB()
{
await Task.Delay(2000);
return "B Done";
}
UniRx would do the same, with extra overhead so that you'd get an Observable object that you'd not use in this context.
You can do the same with coroutines:
IEnumerator Start()
{
string resultA = null;
string resultB = null;
StartCoroutine(AsyncRoutineA((result) => resultA = result));
StartCoroutine(AsyncRoutineA((result) => resultB = result));
yield return new WaitUntil(()=>
{
return !string.IsNullOrEmpty(resultA) && !string.IsNullOrEmpty(resultB);
});
Debug.Log(resultA " " resultB);
}
IEnumerator AsyncRoutineA(Action<string> result)
{
yield return new WaitForSeconds(1);
result.Invoke("A done");
}
IEnumerator AsyncRoutineB(Action<string> result)
{
yield return new WaitForSeconds(2f);
result.Invoke("B done");
}