Выполнение кода пропущено при запросе токена - PullRequest
0 голосов
/ 20 марта 2020

Я запрашиваю токен, но код не выполняется в части SendAsync. Я получаю токен, успешно используя почтальона.

Here is the example snippet:

                string tokenUrl = $"https://myServiceUrl.cognitiveservices.azure.com/sts/v1.0/issuetoken";
                var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
                tokenRequest.Content = new FormUrlEncodedContent(new Dictionary<string, string>
                {
                    ["Content-Type"] = "application/x-www-form-urlencoded",
                    ["Ocp-Apim-Subscription-Key"] = "MyKey"
                });
                HttpClient client = new HttpClient();

                var tokenResponse = await client.SendAsync(tokenRequest); // skipped here 

                dynamic json = await tokenResponse.Content.ReadAsStringAsync();
                var token = JsonConvert.DeserializeObject<string>(json);

Я даже пытался без ["Content-Type"] = "application/x-www-form-urlencoded", но у меня не работает.

1 Ответ

0 голосов
/ 20 марта 2020

Обновление

Оказывается, что действительная причина для "пропуска" остальной части метода - случайно не ожидание вызова GetSpeechServiceToken в родительском методе. Это заставило выполнение потока продолжить в исходном потоке и выйти из метода, по-видимому, пропуская остаток.

OP исправил это, вместо этого назвав его так: GetSpeechServiceToken().Wait() вместо GetSpeechServiceToken()

Если вы столкнулись с подобной проблемой, ниже приведены некоторые интересные чтения от Microsoft, которые go в подробнее об асинхронном программировании с помощью async / await.

В этой статье объясняется более подробно концепция, ниже приведен отрывок

Что происходит в асинхронном c методе

Самое важное, что нужно понять в асинхронном программировании, - это как поток управления перемещается от метода к методу. Следующая диаграмма проведет вас через процесс.

Example of Async Flow

Цифры на диаграмме соответствуют следующим шагам.

  1. Обработчик событий вызывает и ожидает метод AccessTheWebAsync asyn c.

  2. AccessTheWebAsync создает экземпляр HttpClient и вызывает для загрузки асинхронный метод GetStringAsync содержимое веб-сайта в виде строки.

  3. Что-то происходит в GetStringAsync, что приостанавливает его продвижение. Возможно, он должен ждать загрузки веб-сайта или какой-либо другой блокирующей активности. Чтобы избежать блокировки ресурсов, GetStringAsync возвращает управление вызывающей стороне, AccessTheWebAsync.

    GetStringAsync возвращает Task<TResult>, где TResult - строка, а AccessTheWebAsync назначает задачу getStringTask переменная. Задача представляет собой текущий процесс для вызова GetStringAsync с обязательством создавать фактическое строковое значение после завершения работы.

  4. , поскольку getStringTask не ожидалось тем не менее, AccessTheWebAsync может продолжаться с другой работой, которая не зависит от конечного результата от GetStringAsync. Эта работа представлена ​​вызовом синхронного метода DoIndependentWork.

  5. DoIndependentWork - это синхронный метод, который выполняет свою работу и возвращает вызывающей стороне.

  6. AccessTheWebAsync закончилась работа, которую он может выполнить без результата из getStringTask. AccessTheWebAsync next хочет вычислить и вернуть длину загруженной строки, но метод не может вычислить это значение до тех пор, пока метод не получит строку.

    Поэтому AccessTheWebAsync использует оператор await для приостановки его прогресс и передать управление методу, который называется AccessTheWebAsync. AccessTheWebAsync возвращает Task<int> вызывающей стороне. Задача представляет собой обещание выдать целочисленный результат, равный длине загруженной строки.

    Внутри вызывающей стороны (обработчик событий в этом примере) шаблон обработки продолжается. Вызывающий может выполнить другую работу, которая не зависит от результата из AccessTheWebAsync, прежде чем ожидать этого результата, или вызывающий может ожидать немедленно. Обработчик событий ожидает AccessTheWebAsync, а AccessTheWebAsync ожидает GetStringAsync.

  7. GetStringAsync завершается и выдает строковый результат. Строковый результат не возвращается при вызове GetStringAsync так, как вы могли бы ожидать. (Помните, что метод уже возвратил задачу на шаге 3.) Вместо этого строковый результат сохраняется в задаче, которая представляет завершение метода, getStringTask. Оператор ожидания получает результат из getStringTask. Оператор присваивания присваивает полученный результат urlContents.

  8. Когда AccessTheWebAsync имеет строковый результат, метод может вычислить длину строки. Затем работа AccessTheWebAsync также будет завершена, и обработчик ожидающего события может возобновить работу.

Другая статья, опубликованная microsoft о передовых методах асинхронной / ожидающей обработки

Оригинальный ответ

Причина этого не работает, потому что вы неправильно вызываете конечную точку:

Вы можете использовать любую из следующих конечных точек:

https://api.cognitive.microsoft.com/sts/v1.0/issueToken https://myServiceUrl.cognitiveservices.azure.com/sts/v1.0/issuetoken

И запрос может быть таким:

            var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
            tokenRequest.Headers.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

            var client = new HttpClient();

            var tokenResponse = await client.SendAsync(tokenRequest);

            var result = await tokenResponse.Content.ReadAsStringAsync();

Результатом уже является строка со значением токена. Не нужно десериализовать его с помощью Json. Net, это просто вызовет исключение.

...