当我尝试异步检查来自 firebase firestore 的用户名时,Unity 冻结

问题描述

嗨,我正在为我的应用程序构建注册场景,但是当要检查用户名是否存在时,整个 unity 会冻结。

这是我尝试过的所有功能

这是来自 firebase 文档的一个

       public async Task<bool> checkIfExists(string Whattocheck="username",string Texttocheck) {
            FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
            CollectionReference docRef = db.Collection("users");
            Query query = docRef.WhereEqualTo(Whattocheck,Texttocheck);
            QuerySnapshot querySnapshot = await query.GetSnapshotAsync();
            foreach (DocumentSnapshot documentSnapshot in querySnapshot.Documents) {
                return true;
            }


            return false;

        } 

那我试过了

       public async Task<bool> checkIfExists(string Whattocheck,string Texttocheck) {
            FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
            var docRef = db.Collection("users");
            Query docQuery=docRef.WhereEqualTo(Whattocheck,Texttocheck);

            List<DocumentSnapshot> snapshot = new List<DocumentSnapshot>((await docQuery.GetSnapshotAsync()).Documents);
     
            foreach(DocumentSnapshot snap in snapshot) {
                return true;
            }

            return false;

        }

我什至试过这个:

           FirebaseFirestore db = FirebaseFirestore.DefaultInstance;
           var docUser = db.Collection("users");
           Query docRef = docUser.WhereEqualTo(Whattocheck,Texttocheck);

           docRef.GetSnapshotAsync().ContinueWithOnMainThread(task => {
               QuerySnapshot booksQuerySnapshot = task.Result;

               foreach (DocumentSnapshot documentSnapshot in booksQuerySnapshot.Documents) {

                   return true;


               }
               return false;
           });
           return false;

最后一个有效,但由于明显的原因,它总是返回 false

这是我在 firebase 中的用户集合:

https://i.stack.imgur.com/nxZC6.png


编辑:刚刚发现问题是我用来将 Task 转换为 bool 的这个函数

public bool checkIfExistsUsernameConverter(string Texttocheck) {
    return checkIfExists(Texttocheck).Result; 
}

这就是冻结应用程序的原因;


编辑:我解决了冻结问题。问题是我没有在函数引用中放置等待者:

  bool UsernameExists = await Task.Run(() => Database.current.checkIfExistsUsernameConverter(usernameIF.text));

但现在它给了我这个没有行代码参考的错误

ArgumentException: 方法返回类型不兼容 System.Delegate.CreateDelegate(System.Type 类型,System.Object firstArgument,System.Reflection.MethodInfo 方法,System.Boolean throwOnBindFailure,System.Boolean allowClosed)(在:0)

解决方法

Unity 不支持 - 我再说一遍 - 不支持 async/await。 原因是,Unity3D 是一个用 C++ 编写的应用程序,您只需通过互操作与它交互,它们就使用自己的多线程环境。理论上,您可以“以旧方式”创建和管理自己的线程,但这会导致上下文切换,因为它们的系统。 要在 Unity 中使用多线程,您需要使用 JobSystem https://docs.unity3d.com/Manual/JobSystem.html