IsCancellationRequested = true 并转到异常。如何从 API 获得所有响应?

Posted

技术标签:

【中文标题】IsCancellationRequested = true 并转到异常。如何从 API 获得所有响应?【英文标题】:IsCancellationRequested = true and go to exception. How to get all respose from API? 【发布时间】:2021-11-12 19:55:04 【问题描述】:

我正在开发 .net core 3.1。我正在尝试使用https://services.timeanddate.com/ API。

调试时我得到IsCancellationRequested = true 并进入异常。取消该行的请求如下: using var response = await _client.GetAsync(url);

服务

  public class HolidayService : IHolidayService
    
        private readonly HttpClient _client;
        private readonly IHttpClientFactory _clientFactory;

         static string httpaddr = "https://api.xmltime.com";  // I need this url result in post man "https://api.xmltime.com/holidays?accesskey=dYjG8ztthf&secretkey=veUV06dNmrnp7bbaYq0u&version=3&country=ro&year=2021"
      //  static string httpaddr = "https://date.nager.at";   // for this I can get result in postman "https://date.nager.at/api/v3/publicholidays/2020/US"

        static HttpClient Http = new HttpClient()  BaseAddress = new Uri(httpaddr) ;


        public HolidayService(HttpClient client)
        
            _client = client;
            _client.Timeout = TimeSpan.FromMilliseconds(30);
        
        public HolidayService(IHttpClientFactory clientFactory)
        
            _clientFactory = clientFactory;
        

        public async Task<List<Holiday>> GetHolidays(string country, int year)
        
            string url = string.Format($"/holidays?accesskey=dYjG8ztthf&secretkey=veUV06dNmrnp7bbaYq0u&version=3&country=ro&year=2021&lang=en");
           // for url i get IsCancellationRequested = true and go to TaskCanceledException exception . How to solve?
           
            // string url2 = string.Format($"/api/v2/PublicHolidays/2020/US"); // for this ulr2 there is no exception

            var result = new List<Holiday>();
            try
            
                CancellationTokenSource source = new CancellationTokenSource();
                CancellationToken token = source.Token;
                var response = await Http.GetAsync(url, token);

                if (response.IsSuccessStatusCode)
                
                    using var responseStream = await response.Content.ReadAsStreamAsync();
                    result = await JsonSerializer.DeserializeAsync<List<Holiday>>(responseStream);
                
                else
                
                    throw new HttpRequestException(response.ReasonPhrase);
                
                // var response = await _client.GetAsync(url, token);
                // using var response = await _client.GetAsync(url);
            
            // Filter by InnerException.
            catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException)
            
                // Handle timeout.
                Console.WriteLine("Timed out: " + ex.Message);
            
            catch (TaskCanceledException ex)
            
                // Handle cancellation.
                Console.WriteLine("Canceled: " + ex.Message);  // this is my exception
            

            return result;


        

我想知道为什么会出现这个取消异常?对于这个https://date.nager.at,我的代码工作正常,并且得到了例外的 json 结果。但是为什么https://services.timeanddate.com/ API 给出异常并且请求被取消了下面的那一行: using var response = await _client.GetAsync(url);

为什么我无法从这个https://services.timeanddate.com/ API 获得异常结果。

JSON 结果用于https://services.timeanddate.com/ API。:


    "urlid": null,
    "url": null,
    "country": null,
    "name": null,
    "oneliner": null,
    "date": null,
    "types": null,
    "uid": null

如何从这个https://services.timeanddate.com/ API 获得所有响应?

【问题讨论】:

响应包含空值,因为 var result = new Holiday(); 并且它永远不会因为异常而改变。异常表示从服务器获取响应存在问题。能否提供_client的配置? 是的。我还使用另一个 API,它是 https://date.nager.at 它工作正常。但是什么时候使用https://services.timeanddate.com/ 这个我得到了异常。有什么问题? 什么是_client @RowanSmith static string httpaddr = "https://api.xmltime.com"; static HttpClient _client = new HttpClient() BaseAddress = new Uri(httpaddr) ; @hanu 请澄清您的问题。这样写是不可能帮助你的。在问题的第一部分中,您谈到了取消和超时。在您问题的第二部分,您似乎实际上能够从 API 获得响应(因此,不会发生超时),但响应本身的形状并不是您所期望的。 【参考方案1】:

我已经尝试了您的代码子集,如下所示,它工作得非常好。

public static async Task<byte[]> TestUrl()

    HttpClient http = new()  BaseAddress = new Uri("https://api.xmltime.com") ;
    CancellationTokenSource cts = new();

    var response = await http.GetAsync("/holidays?accesskey=dYjG8ztthf&secretkey=veUV06dNmrnp7bbaYq0u&version=3&country=ro&year=2021&lang=en",cts.Token);

    if(response.IsSuccessStatusCode)
        return await response.Content.ReadAsByteArrayAsync();
    else
        throw new HttpRequestException(response.ReasonPhrase);

此函数返回一个包含 JSON 的 byte[]。如果此功能对您不起作用,则表明您可能遇到网络问题。

【讨论】:

我收到了System.Threading.Tasks.TaskCanceledException: The operation was canceled. at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken) 那你有网络问题。您的计算机无法连接到与您的代码无关的 URI。复制完整的 URL 并将其放入网络浏览器以检查发生了什么或在curl 中尝试。您需要对网络连接进行故障排除。 该网址在浏览器中运行良好。

以上是关于IsCancellationRequested = true 并转到异常。如何从 API 获得所有响应?的主要内容,如果未能解决你的问题,请参考以下文章

取消 HttpClient 请求 - 为啥 TaskCanceledException.CancellationToken.IsCancellationRequested 为假?

C# TaskCancellationTokenSource IsCancellationRequested 从未被捕获

在取消和处理 CancellationTokenSource 之间存在延迟是不是可以保证 IsCancellationRequested 将设置为 true?

如何使用 CancellationToken 属性?

连续 WebJobs 和 CancellationToken

随笔,聊一聊任务取消