我从API获取大量数据的代码如下所示
public static async Task<model> GetDataAsyncs(string url)
{
// Initialization.
mymodel responseObj = new mymodel();
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
using (var client = new HttpClient(httpClientHandler))
{
// Setting Base address.
client.BaseAddress = new Uri(apiBasicUri);
// Setting content type.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Initialization.
HttpResponseMessage response = new HttpResponseMessage();
// HTTP Get
response = await client.GetAsync(url ).ConfigureAwait(false);
// Verification
if (response.IsSuccessStatusCode)
{
// Reading Response.
string result = response.Content.ReadAsStringAsync().Result;
responseObj.Status = true;
responseObj.Data = result;
}
}
}
return responseObj;
}
我在我的控制器内调用上面的函数
public ActionResult myActionMethod()
{
string res= helper.GetDataAsync("url").Result.Data;
}
这会引发一个错误system.threading.tasks.taskcanceledexception a task was canceled
。这并不是每次都会发生。有人能指出我在这里做错了什么吗?
发布于 2022-02-16 18:53:43
我不能确定为什么会发生这种情况,但是您的代码中有一些可以清除的危险标志,并且可能会解决这个问题。
首先是.ConfigureAwait(false)
的使用。它会造成一些意想不到的后果,所以我建议你不要使用它。我在我最近写的一篇文章中更多地谈到了这一点。
第二,尽可能使用await
而不是.Result
,这几乎总是如此。使用.Result
也会导致意想不到的、难以调试的后果。在您的代码中,我认为您没有理由不能使用await
。
第三,HttpClient
说:
HttpClient将被实例化一次,并在应用程序的整个生命周期中被重用。为每个请求实例化一个HttpClient类将耗尽重载下可用的套接字数。这将导致SocketException错误。
因此,您可以声明一个静态HttpClient
,并在每次需要时重用它。
第四,没有必要使用这一行:
HttpResponseMessage response = new HttpResponseMessage();
您在这里实例化一个新的HttpResponseMessage
,但在下一行中立即覆盖它。
进行这些更改后,您的代码可能如下所示:
private static HttpClient _client = new HttpClient(
new HttpClientHandler {ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; }}
) {
BaseAddress = new Uri(apiBasicUri),
DefaultRequestHeaders = {
Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
}
};
public static async Task<model> GetDataAsyncs(string url)
{
mymodel responseObj = new mymodel();
var response = await _client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
responseObj.Status = true;
responseObj.Data = result;
}
return responseObj;
}
然后将控制器操作更改为async
并使用await
。
public async Task<ActionResult> myActionMethod()
{
var res = (await helper.GetDataAsync("url")).Data;
}
看看在进行这些更改后,您是否仍然会遇到异常。
https://stackoverflow.com/questions/71144714
复制相似问题