【问题标题】:Unity functions called inside 'task.IsCompleted' stop program from continuing在“task.IsCompleted”中调用的 Unity 函数停止程序继续
【发布时间】:2019-08-18 04:09:45
【问题描述】:

我正在使用 Firebase 实时数据库来存储用户及其朋友的游戏列表。保存数据没有给我带来任何问题,但检索它已经给我带来了几天的问题。每当我检索数据并调用任何 Unity 函数(我测试了 PlayerPrefs.GetString()Instantiate())时,程序都会停止,没有任何错误,但也让我做其他事情,因为它是异步的(下面的代码更好地解释了)。

我尝试通过调试器运行它并使用一堆打印语句来查看问题所在。但是,该程序没有给我任何错误,因此无法调试它。我一直在瞎猜。

我已经设法以最简单的方式重现了这个问题:

using Firebase;
using Firebase.Database;
using Firebase.Unity.Editor;
using UnityEngine;

public class FirebaseData : MonoBehaviour {

    private void Awake() {
        PlayerPrefs.SetString("test", "hello");

        FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("HERE IS THE URL TO MY PROJECT");

        TestRetrieve();
    }

    public void TestRetrieve() {   
        FirebaseDatabase.DefaultInstance.GetReference("users/").GetValueAsync().ContinueWith(task => {
            if (task.IsFaulted) {
                // Handle the error...
            } else if (task.IsCompleted) {
                DataSnapshot snapshot = task.Result;

                print("here");
                PlayerPrefs.GetString("test");
                print("there");
            }
        });
    }
}

您会期望程序先打印“这里”,然后再打印“那里”。但是,只有“这里”被打印,然后“PlayerPrefs.GetString("test);”行后面的任何代码都不会运行。没有给出错误。

这实际上是项目中唯一的脚本,只是附加到一个空的GameObject

奇怪的部分是打印功能和大多数其他与 Unity 无关但只是纯 c# 的功能似乎正在工作。只有 Unity 功能给我带来了麻烦。

【问题讨论】:

  • 我对 Unity 了解不多,但问题是否可能在于该代码在另一个线程中执行?也许某些 Unity 引用必须在 UI 线程中执行?我不知道,只是抛出一些想法......

标签: c# firebase unity3d asynchronous firebase-realtime-database


【解决方案1】:

使用异步事件处理程序以实现更好的语法流。

public class FirebaseData : MonoBehaviour {

    void Start() {
        PlayerPrefs.SetString("test", "hello");    
        FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("HERE IS THE URL TO MY PROJECT");    
        TestRetrieve();
    }

    public void TestRetrieve() {   
        retrieve += onRetrieve;
        retrieve(this, EventArgs.Empty);
    }

    event EventHandler retrieve = delegate { };

    private async void onRetrieve(object sender, EventArgs args) {
        retrieve -= onRetrieve;
        try {
            DataSnapshot snapshot = await FirebaseDatabase.DefaultInstance.GetReference("users/").GetValueAsync();
            print("here");
            PlayerPrefs.GetString("test");
            print("there");
        } catch (Exception ex) {
             // Handle the error here...
        }
    }
}

参考Async/Await - Best Practices in Asynchronous Programming

【讨论】:

  • 谢谢!使用“await”关键字是否会强制对“GetValueAsync()”的调用本质上是同步的,因为它会强制调用等待直到完成?如果是这样,那有关系吗?会影响速度吗?
  • @matematika 如果你的意思是如果它会导致阻塞,不。等待时发生在单独的线程上,完成后将返回当前线程。
猜你喜欢
  • 2018-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-22
  • 2015-10-06
  • 1970-01-01
相关资源
最近更新 更多