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?
CodePudding user response:
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.