简体   繁体   English

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

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

I am new to Unity and C# and trying to query my Firebase Realtime Database, but the code does not block for the callback to finish. 我是Unity和C#的新手,正在尝试查询我的Firebase实时数据库,但是代码并未阻止回调完成。

I have tried implementing callbacks but this does not seem to work. 我尝试实现回调,但这似乎不起作用。

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);
}

In LevelComplete() , Debug.Log("Returned value: " + prevlevelscore.ToString()); LevelComplete()Debug.Log("Returned value: " + prevlevelscore.ToString()); executes before prevlevelscore = result; prevlevelscore = result;之前执行prevlevelscore = result;
I want to make sure that the value of prevlevelscore is updated before executing Debug.Log . 我想确保在执行Debug.Log之前已更新prevlevelscore的值。

Put the rest of the code inside the callback too: 将其余的代码也放入回调中:

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);
    });    
}

Your problem is that your ReadFromDb method returns before being finished. 您的问题是您的ReadFromDb方法在完成之前会返回。 You can solve this issue by putting all your code in the callback (but you won't be able to do that all the time) or you can use the async await pattern. 您可以通过将所有代码放入回调中来解决此问题(但是您将无法始终执行此操作),也可以使用异步等待模式。

Make ReadFromDb async: 使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);
            }
        });
    }

Note the await keywork before your GetValueAsync().ContinueWith because this precise code is asynchronous and needs to be awaited if you want to hold code execution until the result has been fetched. 请注意GetValueAsync().ContinueWith之前的await键盘操作,因为此精确代码是异步的,如果要保留代码执行直到获取结果,则需要等待。

And in your caller: 在您的呼叫者中:

    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);
    }

This method becomes async as well (because asynchronicity propagates). 该方法也将变得异步(因为异步性会传播)。 Again, the await keyword will hold on execution until the readFromDb method has finished. 同样,await关键字将保持执行状态,直到readFromDb方法完成。 Which means that your data will be ready. 这意味着您的数据将准备就绪。

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

相关问题 如何在线程返回池之前阻塞? - How do I block until a thread is returned to the pool? 如何在LINQ中编写此代码块? - How do I write this block of code in LINQ? 如何停止代码的执行,直到我从 Unity 中的 PlayerPref 读取值 - How to stop the execution of the code until I read a value from PlayerPref in Unity 如何使代码等待直到bool发出信号才能继续 - How do i make the code wait until a bool signals it to continue 如何在 @code 块内编写 Blazor HTML 代码? - How do I write Blazor HTML code inside the @code block? 如何使用.NET中的多个并发线程来衡量代码块(线程)执行时间 - How do you measure code block (thread) execution time with multiple concurrent threads in .NET 当在调试控制台中突出显示某些内容时,执行会暂停,直到它未突出显示......我该如何停止这种行为? - When something is highlighted in a debug console, execution just pauses until it's unhighlighted ... how do I stop this behaviour? 如何强制执行到 Catch 块? - How Can I Force Execution to the Catch Block? 阻塞线程直到 WCF 回调被引发? - Block thread until WCF callback is raised? 如何将Console App的代码块转换为Azure Function的代码块? - How do I convert Console App's code block to Azure Function's code block?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM