How can I check if async function is finished?

Hi,

I have read other posts about the same problem but they are not exactly same with my problem. I have created the bool flag to control if the asynchronous function is finished or not. Below snippet is what I am doing right now but the problem is because of while loop Unity freezes as if it never escape while loop but it should break while loop since waitFlag changes in the “getAllElementsAsync” method. Without while loop “getAllElements” method returns the value as null since it returns value before it is changed by “getAllElementsAsync” method. I am open to any other solutions that can solve my problem which is returning value after async method finishes. I have also tried creating coroutine for getAllElementsAsync method but it still returns value before coroutine finishes.

public class DatabaseConnection : MonoBehaviour {

private DataSnapshot dataSnapshot;
private bool waitFlag = true;

    public Datasnapshot getAllElements(){
    getAllElementsAsync();

    while(this.waitFlag){}
    return this.dataSnapshot
    }

    public void getAllElementsAsync(){
        FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("someURL");
        DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
       reference.GetValueAsync().ContinueWith(task => {
            if (task.IsFaulted)
            {
                Debug.Log("not ok");
            }
            else if (task.IsCompleted)
            {
               Debug.Log("ok");
                this.dataSnapshot = task.Result;
                this.waitFlag = false;
         }
        });
    }
}

Use a Coroutine instead of a void → Unity - Scripting API: MonoBehaviour.StartCoroutine

Correct me if I am wrong but Startcoroutine is also async function. I also tried that as I said in the question but it didn’t help.

Coroutine is not async function:


.1. Coroutine is a request to a IEnumerator to get just an element of it at every frame:


.2. Coroutine can start at any frame and can cancel at any frame too.


.3. Coroutine can be finish by itself.


  private IEnumerator SomeCoroutine()
{
    // (1)
    while (condition)
    {
        // (2)
        print(Time.frameCount);
        yield return null;
    }
    // (3)
}

(1) : code on this section will invoke just once at the first frame that coroutine called.


(2) : code on this section will executed per frame while condition is true. (you can think this section as code that you write on Update() method)


(3) : code on this section will call once when condition is false. at this state corotine stoped by itself (by ending the loop)


Note: if you stop the coroutine before the condition section (3) will not reach at all.

Note: section (2) called just per frame and you don’t break the main threat cause of infinite loop.

You provide the function you want to be called back when the data is successfully loaded…

using System.Collections;
using System.Collections.Generic;
using Firebase.Database;
using UnityEngine;
public class CallBackCoroutine : MonoBehaviour {

	private bool waitFlag = false;

	public void GetAll (System.Action<DataSnapshot> callBack) {
		if (waitFlag == false) { // IF it has already started getting the data -> Dont try to retrieve it again
			waitFlag = true;
			StartCoroutine (getAllElementsAsync (callBack));
		}
	}

	private IEnumerator getAllElementsAsync (System.Action<DataSnapshot> callBack) {

		DataSnapshot dataSnapshot = null;

		// FirebaseApp.DefaultInstance.SetEditorDatabaseUrl ("someURL");
		DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
		reference.GetValueAsync ().ContinueWith (task => {
			if (task.IsCompleted)
				dataSnapshot = task.Result;
			else
				Debug.Log ("Task is Faulted --> WAITING");

		});

		yield return new WaitUntil (() => { return dataSnapshot != null; });

		waitFlag = false;
		
		callBack (dataSnapshot);
	}
}

I know coroutine is not async but I say startcoroutine is async. I tried to write getAllElements as coroutine then I called it with startcoroutine but it still returns value before coroutine finishes. I need to use this method from outside of this code so it needa to return value. Is there a way to return value from coroutine and assing it to parameter, like “var constant_value = startcoroutine(getallelements());”