【问题标题】:How to call web API from an http client using a small timeout如何使用小超时从 http 客户端调用 Web API
【发布时间】:2015-05-14 15:55:42
【问题描述】:

我正在处理两个相互通信的 Web API 项目。第一个 Web API 使用 HttpClient 类调用第二个。

我想做的是在调用第二个 Web API 时设置一个短的超时时间(500 毫秒),如果我在那段时间内没有得到响应,就跳过处理结果的下一行客户端,但继续在服务器端处理请求(第二个 API)。

 using (var client = new HttpClient())
 {
       client.DefaultRequestHeaders.Accept.Clear();
       client.Timeout = this.Timeout; // (500ms)
       HttpResponseMessage response = client.PostAsJsonAsync(EndPoint, PostData).Result;

        if (response.IsSuccessStatusCode)
        {
            return response.Content.ReadAsAsync<T>().Result;
        }
        else
        {
                 throw new CustomException()
        }

 }

它在第一个 API 端有效,但是在第二个 API(服务器)中,我得到以下异常:

 "A task was canceled."
 "The operation was cancelled."
 at System.Threading.CancellationToken.ThrowOperationCanceledException()
 at System.Threading.CancellationToken.ThrowIfCancellationRequested()  

我认为这是由于调用的小超时造成的,当第二个 API 仍在处理结果时结束。

如何在第二个 API 中避免这种行为并继续处理请求?

提前致谢。

【问题讨论】:

    标签: c# timeout asp.net-web-api dotnet-httpclient


    【解决方案1】:

    这是预期的行为。当您设置超时并且调用在该时间内没有响应时,任务将被取消并引发该异常。

    顺便说一句,不要使用.Result。这会导致阻塞。标记您的方法async 并使用await

    整个事情应该是这样的:

     using (var client = new HttpClient())
     {
        client.DefaultRequestHeaders.Accept.Clear();
        client.Timeout = this.Timeout; // (500ms)
        try
        {
            HttpResponseMessage response = await client.PostAsJsonAsync(EndPoint, PostData);
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadAsAsync<T>();
            }
            else
            {
                throw new CustomException()
            }
        }
        catch (TaskCanceledException)
        {
            // request did not complete in 500ms.
            return null; // or something else to indicate no data, move on
        }
     } 
    

    【讨论】:

    • 在这种情况下,我需要继续处理第二个 Web API 中的调用,以将结果存储在缓存/数据库结果中。即使任务被取消,我怎么能让它继续处理?
    • 您没有发布整个方法,但我假设由于您在调用成功时返回结果,所以额外的处理发生在其他地方?如果是这样,您可以从 catch 块中返回 null,或其他一些值来向调用者发出信号,表明它没有足够快地获得结果。
    • 显示的方法在第一个API端,是客户端调用第二个API。如果它没有得到结果我只是跳过这个过程,但我的意思是我需要第二个 API 继续处理调用,即使它被客户端取消。第二个 API,服务器,需要完成任务并将其存储在缓存中,独立客户端超时过期。我在第二个 API,服务器端,而不是客户端(第一个 API)端得到异常。
    • 啊,我误解了你的问题。不知道第二个 API 中正在发生“继续处理”。据我所知,服务器应该不知道客户端取消了请求。如果你能够在你的开发环境中重现这个,我会说在第二个 API 中设置一个断点并检查发生了什么。我认为这里还有别的东西在起作用。
    • 谢谢托德,这很有道理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 2022-08-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多