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.Timeoutof 100 seconds elapsing
Could this be caused by the implementation above, or is this definitely a server problem?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With