Home > OS >  Using WhenAll pattern in Unity via UniRx?
Using WhenAll pattern in Unity via UniRx?

Time:10-26

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");
}
  • Related