android - 协程中的异步函数在 Android 上不起作用
问题描述
我正在尝试在我的 Unity 项目中创建使用 Facebook 登录流程。我正在使用 Facebook SDK 和 Firebase 对用户数据进行身份验证并将其存储在在线数据库中。
只有当用户不存在时,我才需要更新数据库。所以我正在使用协程
public void someCodeHere(params){
StartCoroutine(waitForTask(task, uid, name, email));
}
IEnumerator waitForTask(Task<DataSnapshot> task, string uid, string name, string email)
{
while(!task.IsCompleted)
{
Debug.Log("Wait task to coplete");
yield return new WaitForSeconds(1);
}
Debug.Log(task.Result.GetRawJsonValue());
if(task.Result.GetRawJsonValue() == null || task.Result.GetRawJsonValue() == "")
{
HardUpdateUser(uid, name, email);
}
else
{
SetExistingUser(task);
}
}
SetExistingUser 在编辑器和设备上完美运行,但是 HardUpdateUser(uid, name, email); 不能在设备上工作,但在统一编辑器中工作得很好。
这是函数内部的代码:
var status = reference.Child("users").Child(userId).SetRawJsonValueAsync(json).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("CreateUpdateUserInDB was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("CreateUpdateUserInDB encountered an error: " + task.Exception);
return;
}
Debug.LogFormat("User CreateUpdateUserInDB successfully: {0} ({1})",
user.userName, userId);
});
解决方案
所以。我没有得到日志,因为我没有足够的时间,而且我想我太懒了。无论如何,我为我的问题找到了一些解决方法。
我没有提到的事情是我StartCoroutine(waitForTask(task, uid, name, email));
在另一个协程中启动协程(当然是在另一个协程中)。所以我有很多courtines。他们中的大多数人都在等待来自前一个函数等的一些对象。我在 while 循环中使用了一些计数器。例如
while(obj == null && wait > 0) {
wait--;
yield return new WaitForSceonds(1);
}
wait = 15;
//run next coroutine
并且等待变量通常是少数协程之一。所以我改变了什么:
- 我不再等待对象,而是等待完成特殊任务(例如
task.IsCompleted
) - 我已将等待变量更改为时间戳。(例如,我不想等待用户登录超过 15 秒)
所以我的根本问题不在我在问题中提到的代码中。
当我有时间调查 Android 日志并找出协程堆积的原因时,我会更新我的答案。
这是一个带有时间戳的示例:
private IEnumerator SetUserNameToTheTop()
{
while (ux.GetCurrentUser() == null && (DateTime.Now - dataTime).TotalSeconds < 15)
{
pendingTxt.text = (DateTime.Now - dataTime).TotalSeconds.ToString();
Debug.Log("WAIT FOR ERROR");
yield return new WaitForSeconds(1);
}
if (ux.GetCurrentUser() != null && ux.GetCurrentUser().userName != "")
{
ActivateMenu();
}
else
{
PENDING_MSG = "USER WASN'T FOUND, TRY TO SIGN UP FIRST";
pendingTxt.text = PENDING_MSG;
isFailed = true;
FBButtons.SetActive(true);
}
}
推荐阅读
- google-cloud-platform - 我们如何在google cloud deploy中使用cloud build privatePool
- c - 如何创建 n 个线程,每个线程创建 n - 1 个线程
- spring-boot - Spring WebClient - 如果在 doOnError 中引发异常,则停止重试
- snowflake-cloud-data-platform - LAST_DAY('WEEK') 忽略 WEEK_OF_YEAR_POLICY 会话参数
- bash - 数据块 /dbfs 上的“树”命令
- c# - 使用 Visual Studio 代码时如何查找符号的定义?
- sql - 在最初使用多格式逻辑文件的 RPGLE 程序中检索 DB2 记录的最佳实践是什么?
- python-3.x - 如何将“和”搜索运算符添加到 odoo XML-RPC api 调用?
- html - 如何在多个网格上制作内容?
- javascript - Casl Prisma 可以用 vanilla Javascript 编写还是需要 Typescript?