请求令牌时跳过代码执行
Code execution skipped while requesting for token
我正在请求令牌,但代码未在 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"
的情况下尝试过,但对我不起作用。
更新
事实证明,'skipping' 方法其余部分的实际原因是意外地没有等待父方法中对 GetSpeechServiceToken
的调用。这导致线程继续在原始线程上执行并跳出该方法,似乎跳过了其余部分。
OP 通过这样调用它来修复此问题:GetSpeechServiceToken().Wait()
而不是 GetSpeechServiceToken()
如果您 运行 遇到类似的问题,下面是微软的一些有趣读物,其中更详细地介绍了使用 async/await 进行异步编程。
This article更详细地解释了这个概念,下面是摘录
What Happens in an Async Method
The most important thing to understand in asynchronous programming is
how the control flow moves from method to method. The following
diagram leads you through the process.
The numbers in the diagram correspond to the following steps.
An event handler calls and awaits the AccessTheWebAsync
async method.
AccessTheWebAsync
creates an HttpClient
instance and calls the
GetStringAsync
asynchronous method to download the contents of a
website as a string.
Something happens in GetStringAsync
that suspends its progress.
Perhaps it must wait for a website to download or some other blocking
activity. To avoid blocking resources, GetStringAsync
yields control
to its caller, AccessTheWebAsync
.
GetStringAsync
returns a Task<TResult>
where TResult
is a string, and
AccessTheWebAsync
assigns the task to the getStringTask
variable. The
task represents the ongoing process for the call to GetStringAsync
,
with a commitment to produce an actual string value when the work is
complete.
Because getStringTask
hasn't been awaited yet, AccessTheWebAsync
can
continue with other work that doesn't depend on the final result from
GetStringAsync
. That work is represented by a call to the synchronous
method DoIndependentWork
.
DoIndependentWork
is a synchronous method that does its work and
returns to its caller.
AccessTheWebAsync
has run out of work that it can do without a result
from getStringTask
. AccessTheWebAsync
next wants to calculate and
return the length of the downloaded string, but the method can't
calculate that value until the method has the string.
Therefore, AccessTheWebAsync
uses an await operator to suspend its
progress and to yield control to the method that called
AccessTheWebAsync
. AccessTheWebAsync
returns a Task<int>
to the
caller. The task represents a promise to produce an integer result
that's the length of the downloaded string.
Inside the caller (the event handler in this example), the processing
pattern continues. The caller might do other work that doesn't depend
on the result from AccessTheWebAsync
before awaiting that result, or
the caller might await immediately. The event handler is waiting for
AccessTheWebAsync
, and AccessTheWebAsync
is waiting for
GetStringAsync
.
GetStringAsync
completes and produces a string result. The string
result isn't returned by the call to GetStringAsync
in the way that
you might expect. (Remember that the method already returned a task in
step 3.) Instead, the string result is stored in the task that
represents the completion of the method, getStringTask
. The await
operator retrieves the result from getStringTask
. The assignment
statement assigns the retrieved result to urlContents
.
When AccessTheWebAsync
has the string result, the method can calculate the
length of the string. Then the work of AccessTheWebAsync
is also
complete, and the waiting event handler can resume.
Another article published by microsoft about best practices for 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 反序列化它,那只会导致异常。
我正在请求令牌,但代码未在 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"
的情况下尝试过,但对我不起作用。
更新
事实证明,'skipping' 方法其余部分的实际原因是意外地没有等待父方法中对 GetSpeechServiceToken
的调用。这导致线程继续在原始线程上执行并跳出该方法,似乎跳过了其余部分。
OP 通过这样调用它来修复此问题:GetSpeechServiceToken().Wait()
而不是 GetSpeechServiceToken()
如果您 运行 遇到类似的问题,下面是微软的一些有趣读物,其中更详细地介绍了使用 async/await 进行异步编程。
This article更详细地解释了这个概念,下面是摘录
What Happens in an Async Method
The most important thing to understand in asynchronous programming is how the control flow moves from method to method. The following diagram leads you through the process.
The numbers in the diagram correspond to the following steps.
An event handler calls and awaits the
AccessTheWebAsync
async method.
AccessTheWebAsync
creates anHttpClient
instance and calls theGetStringAsync
asynchronous method to download the contents of a website as a string.Something happens in
GetStringAsync
that suspends its progress. Perhaps it must wait for a website to download or some other blocking activity. To avoid blocking resources,GetStringAsync
yields control to its caller,AccessTheWebAsync
.
GetStringAsync
returns aTask<TResult>
whereTResult
is a string, andAccessTheWebAsync
assigns the task to thegetStringTask
variable. The task represents the ongoing process for the call toGetStringAsync
, with a commitment to produce an actual string value when the work is complete.Because
getStringTask
hasn't been awaited yet,AccessTheWebAsync
can continue with other work that doesn't depend on the final result fromGetStringAsync
. That work is represented by a call to the synchronous methodDoIndependentWork
.
DoIndependentWork
is a synchronous method that does its work and returns to its caller.
AccessTheWebAsync
has run out of work that it can do without a result fromgetStringTask
.AccessTheWebAsync
next wants to calculate and return the length of the downloaded string, but the method can't calculate that value until the method has the string.Therefore,
AccessTheWebAsync
uses an await operator to suspend its progress and to yield control to the method that calledAccessTheWebAsync
.AccessTheWebAsync
returns aTask<int>
to the caller. The task represents a promise to produce an integer result that's the length of the downloaded string.Inside the caller (the event handler in this example), the processing pattern continues. The caller might do other work that doesn't depend on the result from
AccessTheWebAsync
before awaiting that result, or the caller might await immediately. The event handler is waiting forAccessTheWebAsync
, andAccessTheWebAsync
is waiting forGetStringAsync
.
GetStringAsync
completes and produces a string result. The string result isn't returned by the call toGetStringAsync
in the way that you might expect. (Remember that the method already returned a task in step 3.) Instead, the string result is stored in the task that represents the completion of the method,getStringTask
. The await operator retrieves the result fromgetStringTask
. The assignment statement assigns the retrieved result tourlContents
.When
AccessTheWebAsync
has the string result, the method can calculate the length of the string. Then the work ofAccessTheWebAsync
is also complete, and the waiting event handler can resume.
Another article published by microsoft about best practices for 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 反序列化它,那只会导致异常。