【发布时间】:2023-03-13 01:02:02
【问题描述】:
在考虑了这个有趣的答案HttpClient.GetAsync(...) never returns... 之后,我仍然遇到使用 await 时我的 HttpClient 没有返回的情况(下面的示例代码)。此外。我在 asp.net MVC5 控制器(UI 驱动)和 WebApi 中都使用了这个帮助程序。我能做什么:
- 使用 await 代替(可怕的) .Result 并且仍然有这个函数返回?
- 在 MVC 控制器和 WebApi 中重复使用相同的例程?
显然,我应该将 .Result 替换为 .ConfigureAwait(false) 但这似乎与上面引用的帖子中的“Task4”与等待 httpClient.GetAsync 一起工作的事实相矛盾。还是我需要单独的控制器和 WebApi 例程?
public static async Task<IEnumerable<TcMarketUserFullV1>> TcSearchMultiUsersAsync(string elasticQuery)
{
if (string.IsNullOrEmpty(elasticQuery)) return null;
IEnumerable<TcMarketUserFullV1> res = null;
using (var hclient = new HttpClient())
{
hclient.BaseAddress = new Uri("https://addr.servicex.com");
hclient.DefaultRequestHeaders.Accept.Clear();
hclient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
hclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",
CloudConfigurationManager.GetSetting("jwt-bearer-token"));
// Why does this never return when await is used?
HttpResponseMessage response = hclient.GetAsync("api/v2/users?q=" + elasticQuery + "&search_engine=v2").Result;
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
res = JsonConvert.DeserializeObject<TcMarketUserFullV1[]>(content).AsEnumerable();
}
else{log.Warn("...");}
}
return res;
}
更新:我的调用链,从 Telerik Kendo Mvc.Grid DataBinding 调用开始如下:
[HttpPost]
public async Task<ActionResult> TopLicenseGrid_Read([DataSourceRequest]DataSourceRequest request)
{
var res = await GetLicenseInfo();
return Json(res.ToDataSourceResult(request)); // Kendo.Mvc.Extensions.DataSourceRequest
}
然后:
private async Task<IEnumerable<CsoPortalLicenseInfoModel>> GetLicenseInfo()
{
...
// Never returns
var qry = @"app_metadata.tc_app_user.country:""DE""";
return await TcSearchMultiUsersAsync(qry);
}
然后,上面完整显示的例程,但现在没有 .Result:
public static async Task<IEnumerable<TcMarketUserFullV1>> TcSearchMultiUsersAsync(string elasticQuery)
{
if (string.IsNullOrEmpty(elasticQuery)) return null;
IEnumerable<TcMarketUserFullV1> res = null;
using (var hclient = new HttpClient())
{
hclient.BaseAddress = new Uri("https://addr.servicex.com");
hclient.DefaultRequestHeaders.Accept.Clear();
hclient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
hclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer",
CloudConfigurationManager.GetSetting("jwt-bearer-token"));
// This now returns fine
HttpResponseMessage response = hclient.GetAsync("api/v2/users?search_engine=v2&q=" + elasticQuery");
if (response.IsSuccessStatusCode)
{
// This returns my results fine too
var content = await response.Content.ReadAsStringAsync();
// The following line never returns results. When debugging, everything flows perfectly until I reach the following line, which never
// returns and the debugger returns me immediately to the top level HttpPost with a result of null.
res = JsonConvert.DeserializeObject<TcMarketUserFullV1[]>(content).AsEnumerable();
}
else{log.Warn("...");}
}
return res;
}
【问题讨论】:
-
您在
hclient.SendAsync中缺少await。 -
我知道。这是因为当我将 await 放在那里时它“挂起”。请注意代码行上方的注释。它将向我提供返回数据的唯一方法是当我使用(可怕的).Result 时。那是我不明白的......
标签: c# asynchronous asp.net-mvc-5 async-await task-parallel-library