Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polly timeout in Blazor WASM Application HttpClient

New to .Net and Blazor. I am trying to extend the timeout of my HTTPClient call (I assume) in my Blazor application. No matter what I do the timeout happens after 10 seconds and a retry initiated, which can be annoying when debugging. I assume this is an HTTPClient timeout, but no matter what I try it seems to timeout after 10 seconds. I check the timeout before the HTTP call and it seems to be the time I set, but it still times out. Am I incorrectly setting the HTTP timeout or is something in Blazor timing out instead?

The code to set the HTTP Client timeout in the Blazor program.cs:

var builder = WebApplication.CreateBuilder(args);

// Add service defaults & Aspire components.
builder.AddServiceDefaults();

// Add services to the container.
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
builder.Services.AddOutputCache();
builder.Services.ConfigureApplicationCookie(ops =>
{
    ops.ExpireTimeSpan = TimeSpan.FromMinutes(30);
    ops.SlidingExpiration = true;
});

builder.Services.AddHttpClient<ModelApiClient>(client =>
{
    // This URL uses "https+http://" to indicate HTTPS is preferred over HTTP.
    // Learn more about service discovery scheme resolution at https://aka.ms/dotnet/sdschemes.
    client.BaseAddress = new("https+http://myapipath/");
    client.Timeout = TimeSpan.FromMinutes(10);
}).SetHandlerLifetime(TimeSpan.FromMinutes(10));

In the Extensions.cs (auto generated when I created the solution) I have:

public static class Extensions
{
    public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder)
    {
        builder.ConfigureOpenTelemetry();

        builder.AddDefaultHealthChecks();

        builder.Services.AddServiceDiscovery();

        builder.Services.ConfigureHttpClientDefaults(http =>
        {
            // Turn on resilience by default
            http.AddStandardResilienceHandler();

            // Turn on service discovery by default
            http.AddServiceDiscovery();
        });

        return builder;
    }

The actual call in the razor file looks like this:

 Debug.WriteLine("Timeout: " + httpClient.Timeout.TotalMinutes);
 var response = await httpClient.PostAsJsonAsync("/api/whatever", singleModel); 

But invariably the call is stopped with this error:

Polly: Warning: Execution attempt. Source: '-standard//Standard-Retry', Operation Key: '', Result: 'The operation didn't complete within the allowed timeout of '00:00:10'.', Handled: 'True', Attempt: '0', Execution Time: 11134.0462ms

Polly.Timeout.TimeoutRejectedException: The operation didn't complete within the allowed timeout of '00:00:10'.
 ---> System.Threading.Tasks.TaskCanceledException: The operation was canceled.
 ---> System.IO.IOException: Unable to read data from the transport connection: The I/O operation has been aborted because of either a thread exit or an application request..
 ---> System.Net.Sockets.SocketException (995): The I/O operation has been aborted because of either a thread exit or an application request.
   --- End of inner exception stack trace ---

Is this an HTTPClient issue or something else?

Tried to extend the life of the HTTPClient call to 10 minutes, but still cancelled after 10 seconds.

like image 696
Age of Empires Avatar asked Sep 13 '25 06:09

Age of Empires


1 Answers

The AddStandardResilienceHandler extension registers a series of resilience strategies. You can read about this in this .NET blog post. One of the strategies is an Attempt Timeout which is enforced against each request. The default value for this timeout is 10 seconds. You can override the value like this:

.AddStandardResilienceHandler(options =>
{
    options.AttemptTimeout.Timeout = TimeSpan.FromSeconds(60);
});

Or if you don't want to have the these resilience strategies during debugging then simple comment out the http.AddStandardResilienceHandler(); line.

like image 186
Peter Csala Avatar answered Sep 15 '25 20:09

Peter Csala