如何使用小超时从http客户端调用Web API

时间:2015-03-12 13:08:39

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

我正在处理两个可以沟通的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中避免此行为并继续处理请求?

提前致谢。

1 个答案:

答案 0 :(得分:0)

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

顺便说一下,不要使用.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
    }
 }