Using values from async function

Hello,

I’m a little confused.
the problem is me and my lack of knowledge.
For this I ask for your help even if I realize that it is a little off-topic.

Problem
I have the ability to retrieve the group list (ListGroupsAsync function).
This list is called in the “OnStart ()” event of my gameManager.
Until here everything seems easy.

I would like to retrieve the list of groups and store them in my own list.
Unfortunately, the list of groups that returns correctly is not accessible outside the task.

What am I doing wrong? Can you help me?

here my code:

public class GameManager : MonoBehaviour
{   
    private NakamaConnection nakamaConnection;
    private GameController gameController;

    private void Awake()
    {
        gameController = GameController.instance;
        nakamaConnection = gameController.nakamaConnection;
   }

    // Start is called before the first frame update
    void Start()
    {
        IApiGroupList groups = ListGroups();

        foreach (var group in groups.Groups). <-- GROUPS IS ALWAYS NULL
        {
            Debug.Log(group.Name);
        }
        Debug.Log("GameManager - ListGroup | Gruppi letti correttamente");

    }

    IApiGroupList ListGroups()
    {
        var task = nakamaConnection.Client.ListGroupsAsync(GameController.instance.nakamaConnection.Session, "Piq400%", 100);

        IApiGroupList result = null;

        var groups = task.ContinueWith(t =>
        {
            foreach (var group in t.Result.Groups)
            {
                Debug.Log(group.Name);
            }
            result = t.Result;
        }, TaskContinuationOptions.OnlyOnRanToCompletion);

        task.ContinueWith(t =>
        {
            Debug.Log("GameManager - ListGroup | Error reading groups " + t.Exception);
        }, TaskContinuationOptions.NotOnRanToCompletion);

        return result;
    }
}

I’d recommend reading up on using async, await, and general C# asynchronous concepts. You can find a great rundown here.

In this bit of code, I’d recommend making your ListGroups() function async. Then change the line where you assign your task variable to something like:

var result = await nakamaConnection.Client.ListGroupsAsync(GameController.instance.nakamaConnection.Session, "Piq400%", 100);

By using the await keyword you avoid having to mess around with all the task.ContinueWith() stuff. Looping through the groups is then as easy as:

foreach(var group in result.Groups) {
    Debug.Log(group.name);
}

And then finally to return the result return result;
The full code could look something like this:

public class GameManager : MonoBehaviour
{   
    private NakamaConnection nakamaConnection;
    private GameController gameController;

    private void Awake()
    {
        gameController = GameController.instance;
        nakamaConnection = gameController.nakamaConnection;
   }

    // Start is called before the first frame update
    async void Start()
    {
        IApiGroupList groups = await ListGroups();

        foreach (var group in groups.Groups)
        {
            Debug.Log(group.Name);
        }
        Debug.Log("GameManager - ListGroup | Gruppi letti correttamente");

    }

    async IApiGroupList ListGroups()
    {
        IApiGroupList result = await nakamaConnection.Client.ListGroupsAsync(GameController.instance.nakamaConnection.Session, "Piq400%", 100);
        return result;
    }
}

Let me know if this works or you need further help!

1 Like

Thank you very much. I really appreciate. Now I read M$ documentation.

There was a little mistake in this row:

async Task<IApiGroupList> ListGroups()

Solved :slight_smile: