C # Как я могу убедиться, чтобы выполнить ожидаемые операции в одном потоке - PullRequest
0 голосов
/ 28 января 2019

Я создаю приложение UWP, которое, очевидно, содержит несколько ожидаемых вызовов асинхронных методов.

В одном из обработчиков событий мне нужно убедиться, что цепочка вызовов выполняется в одном потоке.

Я пытался сделать свою "синхронизирующую" версию асинхронных методов, которая мне нужна, в ожидании и получении результата, что-то вроде этого:

public static T Sync<T>(this Task<T> task)
{
    if (task == null)
        return default(T);
    return task.ConfigureAwait(false).GetAwaiter().GetResult();
}

Или даже еще более брутально:

    public static T Sync<T>(this Task<T> task)
    {
        if (task == null)
            return default(T);
        task.Wait();
        return task.Result;
    }

Но я столкнулся с проблемой тупика, описанной в нескольких других блогах, потому что я работаю в потоке пользовательского интерфейса.

Есть ли способ достичь моей цели?

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Как я могу убедиться, что ожидаемые операции выполняются в одном потоке

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

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

Правильно Решением для этого является исправление вашей логики.Любая альтернатива - в частности, отключение потока пользовательского интерфейса - ухудшит ваш пользовательский опыт и может помешать вашему приложению быть принятым в магазине.

Тем не менее, если вы абсолютно уверены, васЕсли вы хотите пойти по этому пути, а не исправлять свой код, у вас есть два основных варианта:

  1. Сделать весь код синхронным.Он будет работать в потоке пользовательского интерфейса и блокировать его по желанию.
  2. Запустить вложенный цикл обработки сообщений.Я не уверен, поддерживается ли это в UWP;Вы могли бы быть в состоянии заставить что-то работать, используя мой AsyncContext.

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

0 голосов
/ 28 января 2019

Если все, что вам нужно, это сериализовать доступ к состоянию (т.е. вы хотите, чтобы только один поток изменял состояние), вы можете достичь этого, используя один из множества примитивов синхронизации, встроенных в .NET.

Одним из самых простых инструментов является оператор lock.

Конечно, это будет побочным эффектом блокировки ваших Task s, что может не подойти для вашего приложения.Но есть несколько доступных реализаций для «асинхронных» блокировок .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...