Обновление
Оказывается, что действительная причина для "пропуска" остальной части метода - случайно не ожидание вызова GetSpeechServiceToken
в родительском методе. Это заставило выполнение потока продолжить в исходном потоке и выйти из метода, по-видимому, пропуская остаток.
OP исправил это, вместо этого назвав его так: GetSpeechServiceToken().Wait()
вместо GetSpeechServiceToken()
Если вы столкнулись с подобной проблемой, ниже приведены некоторые интересные чтения от Microsoft, которые go в подробнее об асинхронном программировании с помощью async / await.
В этой статье объясняется более подробно концепция, ниже приведен отрывок
Что происходит в асинхронном c методе
Самое важное, что нужно понять в асинхронном программировании, - это как поток управления перемещается от метода к методу. Следующая диаграмма проведет вас через процесс.
Цифры на диаграмме соответствуют следующим шагам.
-
Обработчик событий вызывает и ожидает метод AccessTheWebAsync
asyn c.
AccessTheWebAsync
создает экземпляр HttpClient
и вызывает для загрузки асинхронный метод GetStringAsync
содержимое веб-сайта в виде строки.
Что-то происходит в GetStringAsync
, что приостанавливает его продвижение. Возможно, он должен ждать загрузки веб-сайта или какой-либо другой блокирующей активности. Чтобы избежать блокировки ресурсов, GetStringAsync
возвращает управление вызывающей стороне, AccessTheWebAsync
.
GetStringAsync
возвращает Task<TResult>
, где TResult
- строка, а AccessTheWebAsync
назначает задачу getStringTask
переменная. Задача представляет собой текущий процесс для вызова GetStringAsync
с обязательством создавать фактическое строковое значение после завершения работы.
, поскольку getStringTask
не ожидалось тем не менее, AccessTheWebAsync
может продолжаться с другой работой, которая не зависит от конечного результата от GetStringAsync
. Эта работа представлена вызовом синхронного метода DoIndependentWork
.
DoIndependentWork
- это синхронный метод, который выполняет свою работу и возвращает вызывающей стороне.
AccessTheWebAsync
закончилась работа, которую он может выполнить без результата из getStringTask
. AccessTheWebAsync
next хочет вычислить и вернуть длину загруженной строки, но метод не может вычислить это значение до тех пор, пока метод не получит строку.
Поэтому AccessTheWebAsync
использует оператор await для приостановки его прогресс и передать управление методу, который называется AccessTheWebAsync
. AccessTheWebAsync
возвращает Task<int>
вызывающей стороне. Задача представляет собой обещание выдать целочисленный результат, равный длине загруженной строки.
Внутри вызывающей стороны (обработчик событий в этом примере) шаблон обработки продолжается. Вызывающий может выполнить другую работу, которая не зависит от результата из AccessTheWebAsync
, прежде чем ожидать этого результата, или вызывающий может ожидать немедленно. Обработчик событий ожидает AccessTheWebAsync
, а AccessTheWebAsync
ожидает GetStringAsync
.
GetStringAsync
завершается и выдает строковый результат. Строковый результат не возвращается при вызове GetStringAsync
так, как вы могли бы ожидать. (Помните, что метод уже возвратил задачу на шаге 3.) Вместо этого строковый результат сохраняется в задаче, которая представляет завершение метода, getStringTask
. Оператор ожидания получает результат из getStringTask
. Оператор присваивания присваивает полученный результат urlContents
.
Когда 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, это просто вызовет исключение.