Unity зависает, когда я пытаюсь асинхронно проверить имя пользователя из firebase firestore

#c# #unity3d #google-cloud-firestore #async-await #mobile-application

# #c# #unity3d #google-cloud-firestore #асинхронное ожидание #мобильное приложение

Вопрос:

Привет, я создаю сцену регистрации для своего приложения, но когда она проверяет, существует ли имя пользователя, весь 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.Resu<

               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).Resu< 
}
 

это то, что замораживает приложение;


Редактировать: я решил проблему зависания. Проблема заключалась в том, что я не поместил ожидающий в ссылку на функцию:

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

но теперь он выдает мне эту ошибку без ссылки на код строки:

Исключение ArgumentException: возвращаемый тип метода несовместим с системой.Делегировать.CreateDelegate (System.Введите тип, System.Первый аргумент объекта, System.Отражение.Методинфо метод, система.Логическое значение throwOnBindFailure, System.Логическое значение allowClosed) (при :0)

Комментарии:

1. Так проблема в том, что он зависает или возвращает false? Обратите внимание, что внешняя return обработка уже выполнена задолго до того, как ваш асинхронный снимок был фактически получен… Также ваш внутренний возврат в лямбда-выражении возвращается только из этого лямбда-выражения.. не ваш метод.

2. Проблема в том, что он зависает, за исключением последнего метода, который каждый раз возвращает false по причине, которую вы сказали

Ответ №1:

Unity не поддерживает — я повторяю — не поддерживает async/await . Причина в том, что Unity3D — это приложение, написанное на C , и вы просто взаимодействуете с ним через interop, и они используют свою собственную многопоточную среду. Теоретически вы могли бы создавать и управлять своими собственными потоками «по-старому», но это вызвало бы переключение контекста из-за их системы. Чтобы использовать многопоточность в Unity, вам необходимо использовать JobSystem https://docs.unity3d.com/Manual/JobSystem.html

Комментарии:

1. Я не в первый раз использую async / await в unity, это работает каждый раз, за исключением этого случая

2. ..Пока вы не создадите свою игру 🙂 Дело в том, что официально Unity даже не пытается исправить что-либо, связанное с async / await в их собственной пользовательской среде выполнения Mono, что означает, что она не поддерживается. Это не только еще менее эффективно, чем использование синхронного кода, это плохая практика, а не стандарт Unity. Кроме того, система заданий действительно хорошо сделана. Помните: Async / await не является потокобезопасным; Система заданий является. Но, эй, это ваш выбор : D