Search code examples
c#asp.net-corehttpclientwebservice-clienthttpclientfactory

ASP.NET Core with HttpClientFactory : best practice?


I have an ASP.NET Core application which needs to cyclically call a web service.

I instantiated a HostedService:

public class MyHostedService : IHostedService
{
    public MyHostedService(IMyWebServiceClient MyWebServiceClient)
    {
      ...
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
       while (!cancellationToken.IsCancellationRequested)
       {
           var result = await myWebServiceClient.CallSomeWebApi();

           await Task.Delay(5000, cancellationToken);
       }

       return Task.CompletedTask;
    }
}

which calls some function from a WebServiceClient class. The class looks like this

public class MyWebServiceClient: IMyWebServiceClient
{
    private readonly IHttpClientFactory httpClientFactory;

    public MyWebServiceClient(IHttpClientFactory httpClientFactory)
    {
        this.httpClientFactory = httpClientFactory;
    }

    public async Task CallSomeWebApi()
    {
       using (var httpClient = httpClientFactory.CreateClient())
       {
           var requestMessage = new HttpRequestMessage(...);

           var response = await httpClient.SendAsync(requestMessage);
       }
    }
}

The startup code is this:

public void ConfigureServices(IServiceCollection services)
{
    ....
    services.AddHttpClient();
    services.AddSingleton<IMyWebServiceClient, MyWebServiceClient>();
    services.AddHostedService<MyHostedService>();
    ....
}

Can somebody tell me if it is a good practice calling cyclically

var httpClient = httpClientFactory.CreateClient()

(for instance every 5 seconds)?

Could some side effects occur because of this? I am testing with some Web Server and quite often getting an exception

The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing

Could this be caused by the implementation above, or is this definitely a server problem?


Solution

  • The error that you get is because the client API call times out after 100 seconds which is the default timeout so this is probably the server not responding.

    It should be fine to create a new HttpClient every five seconds. The HttpClient instance wraps a pooled HttpMessageHandler so it's lightweight (as opposed to the pooled handler). Disposing it doesn't dispose the handler which otherwise could lead to resource exhaustion (client sockets aren't released immediately).

    Because the inner handler by default is configured to "refresh itself" at regular intervals to pick up new DNS information you actually don't need to use IHttpClientFactory yourself. You can instead inject HttpClient directly using a typed client as described in Make HTTP requests using IHttpClientFactory in ASP.NET Core. The article Use IHttpClientFactory to implement resilient HTTP requests also explains "best practices" for using HttpClient in .NET.