[英]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.