繁体   English   中英

我如何正确地阻止代码执行直到回调

[英]How do I properly block code execution until callback

我是Unity和C#的新手,正在尝试查询我的Firebase实时数据库,但是代码并未阻止回调完成。

我尝试实现回调,但这似乎不起作用。

static public void ReadFromDb(int level, Action<int> callback) 
{
    int return_value = -1;
    string sessionId = PlayerPrefs.GetString("SessionID");

    FirebaseDatabase.DefaultInstance.GetReference("users/"+sessionId).GetValueAsync().ContinueWith(task => {
        if (task.IsFaulted) 
        {
            // Handle the error...
            Debug.Log("Task faulted");
            callback(return_value);
        } 
        else if (task.IsCompleted) 
        {
            DataSnapshot snapshot = task.Result;
            string score_string = (snapshot.Child(level.ToString()).Value).ToString();
            Debug.Log("score_string " + score_string);
            return_value = int.Parse(score_string);
            callback(return_value);
        }
    });
}


public void LevelComplete() 
{
    DatabaseCode.writeDatabase(SceneManager.GetActiveScene().buildIndex + 1, counter);
    DatabaseCode.ReadFromDb(SceneManager.GetActiveScene().buildIndex + 1, (result) => {
        prevlevelscore = result;
        Debug.Log("result " + result.ToString());
    });
    prevscore = prevlevelscore;
    Debug.Log("Returned value: " + prevlevelscore.ToString());
    SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}

LevelComplete()Debug.Log("Returned value: " + prevlevelscore.ToString()); prevlevelscore = result;之前执行prevlevelscore = result;
我想确保在执行Debug.Log之前已更新prevlevelscore的值。

将其余的代码也放入回调中:

public void LevelComplete() 
{
    DatabaseCode.writeDatabase(SceneManager.GetActiveScene().buildIndex + 1, counter);
    DatabaseCode.ReadFromDb(SceneManager.GetActiveScene().buildIndex + 1, (result) => {
        Debug.Log("result " + result.ToString());
        prevscore = result;
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
    });    
}

您的问题是您的ReadFromDb方法在完成之前会返回。 您可以通过将所有代码放入回调中来解决此问题(但是您将无法始终执行此操作),也可以使用异步等待模式。

使ReadFromDb异步:

    static public async Task ReadFromDb(int level, Action<int> callback) 
    {
        int return_value = -1;
        string sessionId = PlayerPrefs.GetString("SessionID");

        await FirebaseDatabase.DefaultInstance.GetReference("users/"+sessionId).GetValueAsync().ContinueWith(task => {
            if (task.IsFaulted) 
            {
                // Handle the error...
                Debug.Log("Task faulted");
                callback(return_value);
            } 
            else if (task.IsCompleted) 
            {
                DataSnapshot snapshot = task.Result;
                string score_string = (snapshot.Child(level.ToString()).Value).ToString();
                Debug.Log("score_string " + score_string);
                return_value = int.Parse(score_string);
                callback(return_value);
            }
        });
    }

请注意GetValueAsync().ContinueWith之前的await键盘操作,因为此精确代码是异步的,如果要保留代码执行直到获取结果,则需要等待。

在您的呼叫者中:

    public async Task LevelComplete() 
    {
        DatabaseCode.writeDatabase(SceneManager.GetActiveScene().buildIndex + 1, counter);
        await DatabaseCode.ReadFromDb(SceneManager.GetActiveScene().buildIndex + 1, (result) => {
            prevlevelscore = result;
            Debug.Log("result " + result.ToString());
        });
        prevscore = prevlevelscore;
        Debug.Log("Returned value: " + prevlevelscore.ToString());
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
    }

该方法也将变得异步(因为异步性会传播)。 同样,await关键字将保持执行状态,直到readFromDb方法完成。 这意味着您的数据将准备就绪。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM