Проблема основного потока с Parse.com запросы

#c# #unity3d #parse-platform

#c# #unity3d #синтаксический анализ-платформа

Вопрос:

Я пытаюсь использовать parse.com служите с моей игрой Unity. Моя проблема заключается в создании экземпляров объектов в соответствии с результатами, полученными от запроса.

Например, когда я запускаю приведенный ниже код;

 var queryCurrent = ParseObject.GetQuery("Levels")
.WhereEqualTo("ItemId", "Character")
.WhereEqualTo("Level", "3");

queryCurrent.FirstAsync().ContinueWith(t =>
{
    Character character = ScriptableObject.CreateInstance<Character>();
});
 

Я получаю следующую ошибку;

CreateInstanceFromType может быть вызван только из основного потока. Конструкторы и инициализаторы полей будут выполняться из потока загрузки при загрузке сцены. Не используйте эту функцию в конструкторе или инициализаторах полей, вместо этого переместите код инициализации в функцию пробуждения или запуска.

Кажется, что это общая проблема, и все пытаются найти обходной путь, используя сопрограммы. Оптимизированное решение будет оценено по достоинству.

Заранее спасибо.

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

1. Действительно ли это parse.com проблема или скорее просто асинхронная проблема? Ошибка довольно очевидна, что вам нужно создать объекты в основном потоке.

2. В моем случае у меня проблема с parse.com служба, но в целом это должно быть общей проблемой для асинхронных операций в unity…

Ответ №1:

Используйте сопрограмму для запуска в основном потоке. Это задокументировано на сайте синтаксического анализа здесь: https://parse.com/docs/unity_guide#tasks-coroutines

Редактировать:

Unity предоставляет понятие сопрограммы для совместной многозадачности, позволяя чередовать код во время выполнения в основном потоке. Задачи и модель продолжения в основном не зависят от этого механизма многозадачности, но их легко адаптировать для работы в сопрограмме. Ваша сопрограмма может просто проверить свойство IsCompleted задачи, чтобы узнать, завершена ли асинхронная работа, что позволяет сопрограмме продолжить с того места, где она остановилась. Например, следующий код сопрограммы сохраняет объект, а затем ожидает возврата запроса:

 public IEnumerator GameOver()
{
    var gameHistory = new ParseObject("GameHistory");
    gameHistory["score"] = score;
    gameHistory["player"] = ParseUser.CurrentUser;

    var saveTask = gameHistory.SaveAsync();
    while (!saveTask.IsCompleted) yield return null;

    // When the coroutine reaches this point, the save will be complete

    var historyQuery = new ParseQuery<ParseObject>("GameHistory")
        .WhereEqualTo("player", ParseUser.CurrentUser)
        .OrderByDescending("createdAt");

    var queryTask = historyQuery.FindAsync();
    while (!queryTask.IsCompleted) yield return null;

    // The task is complete, so we can simply check for its result to get
    // the current player's game history
    var history = queryTask.Resu<
}