HttpClient超时似乎不起作用

时间:2018-01-23 20:38:13

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

我有一个Web API控制器,如下所示:

[Route("api/[controller]")]
public class SlowController : Controller
{
    [HttpPost]
    public ActionResult Post([FromBody]SlowRequest request)
    {
        var response = new SlowResponse();
        response.Id = request.Id;
        response.StartDate = DateTime.Now;
        Thread.Sleep(new TimeSpan(0, 3, 0));
        response.EndDate = DateTime.Now;

        return Ok(response);
    }
}

注意有3分钟的睡眠时间。这是为了模拟后期动作需要很长时间才能返回。

我有一个调用此Web API的客户端控制台应用程序:

static void Main(string[] args)
{
    try
    {
        var request = new SlowRequest();
        request.Id = Guid.NewGuid();

        var json = JsonConvert.SerializeObject(request);

        var httpClient = new HttpClient();
        httpClient.Timeout = new TimeSpan(0, 5, 0);
        httpClient.BaseAddress = new Uri("http://localhost:54316/");
        var result = httpClient.PostAsync("api/slow", new StringContent(json, Encoding.UTF8, "application/json")).Result.EnsureSuccessStatusCode();
        var apiResponse = result.Content.ReadAsStringAsync().Result;
        var response = JsonConvert.DeserializeObject<SlowResponse>(apiResponse);

        Console.WriteLine("Start Time = " + response.StartDate);
        Console.WriteLine("End Time = " + response.EndDate);

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

不幸的是,客户在2分钟后抛出异常说:

  

响应状态代码不表示成功:502(Bad Gateway)。

似乎如果API返回此时间超过2分钟,则会发生异常。 2分钟以下,它运作得很好。尽管事实上我在客户端上放了5分钟的超时。如何防止因此错误而花费很长时间的Web API调用?

1 个答案:

答案 0 :(得分:3)

问题不是来自客户端,问题来自服务器。你正在睡觉3分钟,这超过了默认的请求超时。您可以在web.config中更改它:

<aspNetCore requestTimeout="00:05:00" ... />

请注意,该值必须仅在整分钟内指定,否则默认为2分钟。请参阅Core configuration reference

Kersel还有2分钟的超时时间需要在Program.cs中更改:

.UseKestrel(o => o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(5));

请参阅Keep​Alive​Timeout Property

注意:我认为您的项目是Core。如果情况并非如此,则必须更改web.config中的executionTimeout属性。默认为110秒:

<system.web>
    <httpRuntime executionTimeout="300" />
</system.web>

请参阅ExecutionTimeout Property