调用 WebAPI 的客户端卡在等待中
本文关键字:在等待 客户端 WebAPI 调用 | 更新日期: 2023-09-27 18:05:45
我有一个调用WebAPI服务的httpclient。GET到达服务并返回内容,但客户端只是一直在等待...
客户端代码:
static async Task RunAsyncGet(string baseUri, string uri)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(baseUri);
HttpResponseMessage response = await client.GetAsync(uri); // <-- stuck here
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
IEnumerable<UserAccountModel> users = await response.Content.ReadAsAsync<IEnumerable<UserAccountModel>>();
//...
}
}
}
网络接口代码:
public class UserAccountController : ApiController
{
private IRepository _repo;
public UserAccountController(IRepository repo)
{
_repo = repo;
}
public HttpResponseMessage Get()
{
var s = _repo.GetAllUserAccounts();
IContentNegotiator negotiator = Configuration.Services.GetContentNegotiator();
ContentNegotiationResult result = negotiator.Negotiate(typeof(AuthResponseModel), Request, Configuration.Formatters);
var bestMatchFormatter = result.Formatter;
var mediaType = result.MediaType.MediaType;
return new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new ObjectContent<IQueryable<UserAccount>>(s, bestMatchFormatter, mediaType)
};
}
}
思潮?
在客户端代码的更上方(无论最终调用RunAsyncGet
(,某些代码正在调用Task.Wait
或Task<T>.Result
。如果从 UI 线程调用,这将导致死锁,正如我在博客上解释的那样。
正确的解决方案是更改该Wait
/Result
以使用await
。
这就是我最终调用 WebAPI 的方式:
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:23302");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("api/useraccount").Result;
if (response.IsSuccessStatusCode)
{
var t = response.Content.ReadAsAsync<IEnumerable<UserAccount>>().Result;
...
}
else
{
//Something has gone wrong, handle it here
}
}
看来你打电话给EnsureSuccessStatusCode
可能是罪魁祸首。该方法实际上返回一个 HTTP 状态在 200 范围内的HttpResponseMessage
,或者将引发异常。因此,您可能需要类似以下内容:
static async Task RunAsyncGet(string baseUri, string uri)
{
var client = new HttpClient();
client.BaseAddress = new Uri(baseUri);
HttpResponseMessage response = await client.GetAsync(uri);
IEnumerable<UserAccountModel> users = await response.EnsureSuccessStatusCode().Content.ReadAsAsync<IEnumerable<UserAccountModel>>();
// ... the rest ...
}