Как исправить «можно вызывать только из основного потока» внутри метода ContinueWith - PullRequest
0 голосов
/ 08 января 2019

У меня проблема при попытке манипулировать объектами GameObject внутри метода ContinueWith экземпляра Task. Код ниже работал довольно хорошо, пока мы не перешли на .NET 4.x в Unity 2018.2.

Я много искал и пытался найти то, что кажется обходным (используя UnityThread), я не смог найти причину, по которой этот код больше не работает, и так как этот шаблон часто используется в мой проект, я хочу знать, если на самом деле нет другого решения.

FirebaseDatabaseManager.Instance.GetPrivateChatMessages(chatId)
    .ContinueWith(messagesTask =>
    {
        if (messagesTask.IsCompleted && messagesTask.Result != null && messagesTask.Result.Exists)
        {
            // Go over the dictionary in reverse.
            foreach (var message in messagesTask.Result.Children.OrderByDescending(x => x.Key))
            {
                Debug.Log("Message " + message.Key);

                // Insert the message as the first element.
                StartCoroutine(AddMessageItem(message));
            }
        }
    });

РЕДАКТИРОВАТЬ: Это метод GetPrivateChatMessages.

/// <summary>
/// Returns the private chats' messages or null if the database is not initialized.
/// </summary>
/// <returns></returns>
public Task<DataSnapshot> GetPrivateChatMessages(string chatId, int limit, string lastItemKey, long lastItemTimestamp)
{
    if (!Initialized) return null;

    return DatabaseRoot.Child("messages").Child(chatId).OrderByChild("timestamp").EndAt(lastItemTimestamp, lastItemKey).LimitToLast(limit).GetValueAsync();
}

Перед обновлением строка StartCoroutine (AddMessageItem (message)); раньше работал просто отлично, теперь выдает исключение

01-08 13: 47: 15.376 23882-24991 / com.fhacktions E / Unity:
IsObjectMonoBehaviour можно вызывать только из основного потока.
& ensp; & ensp; Конструкторы и инициализаторы полей будут выполняться из загрузка потока при загрузке сцены.
& ensp; & ensp; Не используйте эту функцию в инициализаторы конструктора или поля, вместо этого переместите код инициализации в функция пробуждения или запуска.
& EnSP; & EnSP; UnityEngine.MonoBehaviour: StartCoroutine (IEnumerator)
& EnSP; & EnSP; Fhacktions.c__AnonStorey2: <> m__0 (Task`1)
& EnSP; & EnSP; System.Threading.Tasks.Task: Выполнить () * +1019 * & ensp; & ensp; System.Threading.ExecutionContext: RunInternal (ExecutionContext, ContextCallback, Object, Boolean)
& ensp; & ensp; System.Threading.ExecutionContext: Run (ExecutionContext, ContextCallback, Object, Boolean)
& EnSP; & EnSP; System.Threading.Tasks.Task: ExecuteWithThreadLocal (Целевой &) * * тысяча двадцать-дв & EnSP; & EnSP; System.Threading.Tasks.Task: ExecuteEntry (Boolean) * * тысяча двадцать-три & EnSP; & EnSP; System.Threading.ThreadPoolWorkQueue: отправка ()
& EnSP; & EnSP;
& ensp; & ensp; [/ Users / builduser / buildslave / unity / build / Runtime / Scripting / ScriptingThreadAndSerializationSafeCheck.cpp строка 85]
& ensp; & ensp; (Имя файла: /Users/builduser/buildslave/unity/build/Runtime/Scripting/ScriptingThreadAndSerializationSafeCheck.cpp Li

EDIT : Передача TaskScheduler.FromCurrentSynchronizationContext () в качестве параметра методу ContinueWith решает проблему, я думаю, что реализация по умолчанию изменилась, и это вызвало проблему после переключения. Спасибо.

...