c# - 请求令牌时跳过代码执行
问题描述
我正在请求令牌,但代码未按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"
但对我不起作用。
解决方案
更新
事实证明,“跳过”该方法的其余部分的实际原因是意外地没有等待GetSpeechServiceToken
父方法中的调用。这导致线程在原始线程上继续执行并退出该方法,似乎跳过了其余部分。
OP 解决了这个问题,而是像这样调用它:GetSpeechServiceToken().Wait()
而不是GetSpeechServiceToken()
如果您遇到类似的问题,以下是微软的一些有趣读物,其中更详细地介绍了使用 async/await 进行异步编程。
这篇文章更详细地解释了这个概念,下面是摘录
在异步编程中要理解的最重要的事情是控制流如何从一个方法移动到另一个方法。下图将引导您完成整个过程。
图中的数字对应于以下步骤。
事件处理程序调用并等待
AccessTheWebAsync
异步方法。
AccessTheWebAsync
创建一个HttpClient
实例并调用GetStringAsync
异步方法以字符串形式下载网站内容。发生了一些事情
GetStringAsync
,暂停了它的进展。也许它必须等待网站下载或其他一些阻止活动。为了避免阻塞资源,GetStringAsync
将控制权交给调用者,AccessTheWebAsync
.
GetStringAsync
返回一个Task<TResult>
whereTResult
是一个字符串,AccessTheWebAsync
并将任务分配给getStringTask
变量。该任务表示对 的调用的正在进行的过程GetStringAsync
,并承诺在工作完成时产生一个实际的字符串值。因为
getStringTask
还没有等待,AccessTheWebAsync
所以可以继续其他不依赖于最终结果的工作GetStringAsync
。该工作由对同步方法的调用表示DoIndependentWork
。
DoIndependentWork
是一个同步方法,它完成它的工作并返回给它的调用者。
AccessTheWebAsync
如果没有getStringTask
.AccessTheWebAsync
next 想要计算并返回下载的字符串的长度,但是该方法无法计算该值,直到该方法具有该字符串。因此,
AccessTheWebAsync
使用 await 运算符来暂停其进度并将控制权交给调用的方法AccessTheWebAsync
。AccessTheWebAsync
将 a 返回Task<int>
给调用者。该任务代表了一个承诺,即产生一个整数结果,该结果是下载字符串的长度。在调用者(本例中的事件处理程序)内部,处理模式继续进行。调用者可能会在等待结果之前执行不依赖于结果的其他工作
AccessTheWebAsync
,或者调用者可能会立即等待。事件处理程序正在等待AccessTheWebAsync
,并且AccessTheWebAsync
正在等待GetStringAsync
。
GetStringAsync
完成并产生一个字符串结果。调用不会以GetStringAsync
您可能期望的方式返回字符串结果。(请记住,该方法已经在步骤 3 中返回了一个任务。)相反,字符串结果存储在表示方法完成的任务中,getStringTask
. await 运算符从 中检索结果getStringTask
。赋值语句将检索到的结果赋值给urlContents
.当
AccessTheWebAsync
有字符串结果时,该方法可以计算字符串的长度。然后 的工作AccessTheWebAsync
也完成了,等待的事件处理程序就可以恢复了。
微软发表的另一篇关于 async/await 最佳实践的文章
原始答案
它不起作用的原因是因为您没有正确调用端点:
您可以使用以下任一端点:
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 对其进行反序列化,这只会导致异常。
推荐阅读
- typescript - 从长字符串 Typescript 中删除特定字符
- python - 在单个单元格而不是单独的单元格中打印多个值
- python - 在python中按两个值排序。一升一降
- angular - 为什么每次到达 Angular 延迟加载模块下的页面时都会初始化 NgRx 存储?
- sql - 计算平衡体积的窗口函数
- symfony - 无法使用多个提供商和防火墙注销 Symfony 5
- selenium - 无法通过 xpath 索引(硒)获取元素
- javascript - 方法 map() - 一次从后端数组获取所有对象值
- user-interface - 我的 Oculus 耳机干扰了我的 UI 滚动。我的光线交互器可以工作,但头显的移动也可以控制滚动
- google-apps-script - OnSelectionChange 与 SpreadsheetApp.getUI().alert("Message") 不一致 - Google Apps 脚本