【发布时间】:2020-11-25 04:07:06
【问题描述】:
考虑这个名为 Forward 的非异步方法,当使用 Forward(forwardUrl, content); 调用(在 C# 中)时,它的工作方式与预期完全一样
private ActionResult Forward(string forwardUrl, FormUrlEncodedContent content)
{
// NOTE - httpClient is a static HttpClient instance
HttpResponseMessage response;
switch (Request.RequestType.ToUpperInvariant())
{
case "GET":
response = httpClient.GetAsync(forwardUrl).GetAwaiter().GetResult();
break;
case "POST":
response = httpClient.PostAsync(forwardUrl, content).GetAwaiter().GetResult();
break;
default:
throw new InvalidOperationException($"Unable to forward Request method {Request.RequestType}.");
}
if (response.IsSuccessStatusCode)
{
return Content(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), response.Content.Headers.ContentType.ToString());
}
return new HttpStatusCodeResult(response.StatusCode, response.ReasonPhrase);
}
那个工作正常,但反复调用GetAwaiter().GetResult() 基本上阻塞并使其同步。
现在我有以下称为ForwardAsync 的异步方法,在这里我使用完全相同的参数调用它,但使用ForwardAsync(forwardUrl, content).GetAwaiter().GetResult(); 的调用模式
private async Task<ActionResult> ForwardAsync(string forwardUrl, FormUrlEncodedContent content)
{
HttpResponseMessage response;
switch (Request.RequestType.ToUpperInvariant())
{
case "GET":
response = await httpClient.GetAsync(forwardUrl);
break;
case "POST":
response = await httpClient.PostAsync(forwardUrl, content);
break;
default:
throw new InvalidOperationException($"Unable to forward Request method {Request.RequestType}.");
}
if (response.IsSuccessStatusCode)
{
return Content(await response.Content.ReadAsStringAsync(), response.Content.Headers.ContentType.ToString());
}
return new HttpStatusCodeResult(response.StatusCode, response.ReasonPhrase);
}
这个只是挂了。在我的测试用例中,我将沿着POST 分支(在两种情况下),但代码永远不会从await httpClient.PostAsync(forwardUrl, content) 返回。我能够确认请求已发布,并且代码确实在转发的 URL 上运行并响应,但等待的方法调用根本不返回。
我做错了什么?
【问题讨论】:
-
你能显示调用
ForwardAsync的代码吗 -
在描述中-
return ForwardAsync(forwardUrl, content).GetAwaiter().GetResult(); -
不要阻止
async方法,期间。但是,如果您真的需要这样做(在正常情况下很少需要这样做),请牺牲一个线程池线程并卸载它,然后运行任务然后阻止它。 -
您可能想要edit 帖子的标题,因为听起来您实际上并不想在控制器中正确使用 async/await,而是正确地从同步方法中调用异步方法(实际上不是一个好主意,但与您的问题无关)
-
请澄清您是使用
ForwardAsync(forwardUrl, content).GetAwaiter().GetResult()(在您的测试中)调用您的控制器端点还是使用HttpClient进行真正的HTTP 调用?
标签: c# asp.net-mvc async-await