相关疑难解决方法(0)

我怎么知道HttpClient何时超时?

据我所知,没有办法知道它特别是发生了超时.我不是在寻找合适的地方,还是我错过了更大的东西?

string baseAddress = "http://localhost:8080/";
var client = new HttpClient() 
{ 
    BaseAddress = new Uri(baseAddress), 
    Timeout = TimeSpan.FromMilliseconds(1) 
};
try
{
    var s = client.GetAsync("").Result;
}
catch(Exception e)
{
    Console.WriteLine(e.Message);
    Console.WriteLine(e.InnerException.Message);
}
Run Code Online (Sandbox Code Playgroud)

返回:

发生了一个或多个错误.

任务被取消了.

c# timeout dotnet-httpclient

123
推荐指数
6
解决办法
11万
查看次数

HttpClient Polly WaitAndRetry 策略

有人知道为什么下面的策略在 3 次而不是 10 次后停止重试吗?

IAsyncPolicy<HttpResponseMessage> httpWaitAndRetryPolicy =
     Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
          .OrHandle<Exception>(r => true)
          .WaitAndRetryAsync(10, retryAttempt => TimeSpan.FromSeconds(2));
Run Code Online (Sandbox Code Playgroud)

我将重试尝试设置为 10 并测试 http post 调用,但 BadRequest 失败。但只重试了3次就停止了,直到超时并抛出异常

IAsyncPolicy<HttpResponseMessage> httpWaitAndRetryPolicy =
     Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
          .OrHandle<Exception>(r => true)
          .WaitAndRetryAsync(10, retryAttempt => TimeSpan.FromSeconds(2));
Run Code Online (Sandbox Code Playgroud)
var serviceProvider = serviceConnection.AddHttpClient(connection.Name, c =>
        {
            c.BaseAddress = new Uri(connection.BaseUrl);
            c.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{connection.UserName}:{connection.Password}")));
            c.Timeout = connection.Timeout; // Timeout is TimeSpan.FromSeconds(120)
        })
    .AddPolicyHandler(httpWaitAndRetryPolicy)
    .Services.BuildServiceProvider();

HttpClientFactories.Add(connection.Name, serviceProvider.GetService<IHttpClientFactory>());
Run Code Online (Sandbox Code Playgroud)

确认了问题的根本原因:我不知道是什么原因导致了该症状,但看起来请求连接不会被释放,除非显式调用Dispose HttpResponseMessage OnRetry. 当前的解决方案是设置OnRetryWaitAndRetryAsync配置响应。一切正常,无需更改ServicePointManager.DefaultConnectionLimit

c# rest dotnet-httpclient polly retry-logic

5
推荐指数
1
解决办法
9057
查看次数

在 Polly 库中使用 httpclient 的指数退避

我刚刚读到Polly 库,当从桌面代理到服务器通信时,我需要处理 3 次重试。

目前我喜欢指数退避。

但是,我很难理解如何在我的代码中实现这一点。这是我到目前为止所做的:

using (HttpClient client = new HttpClient())
{
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);
    client.DefaultRequestHeaders.Add("TenantId", tenantId);
#if DEBUG
    var url = "http://localhost:5001/api/v1/RetrievePaymentDetails?orderpaymentid={orderPaymentId";
#else
    //TODO: add URL once the application is in production!
    var url = "intent2.api";
#endif
    Policy
        .Handle<HttpRequestException>()
        .WaitAndRetry(new[]
        {
            TimeSpan.FromSeconds(5),
            TimeSpan.FromSeconds(15),
            TimeSpan.FromSeconds(30)
        });

    using (HttpResponseMessage response = await client.GetAsync($"{url}"))
    {
        using (HttpContent content = response.Content)
        {
            HttpContentHeaders headers = content.Headers;
            var result = JsonConvert.DeserializeObject<PaymentDetailsDto>(response.Content.ReadAsStringAsync().Result);
            Currency currencyFromDb = (Currency)Enum.Parse(typeof(Currency), result.Currency);
            var result2 = …
Run Code Online (Sandbox Code Playgroud)

c# httpresponse dotnet-httpclient polly retry-logic

5
推荐指数
2
解决办法
6780
查看次数

Polly CircuitBreakerAsync 没有按我的预期工作

我只是尝试 Polly CircuitBreakerAsync,但它没有按我的预期工作。

我在这里做错了什么?我希望下面的代码完成并表示电路仍然闭合。

using Polly; 
using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main(string[] args)
    {
        MainAsync(args).GetAwaiter().GetResult();
    }
    
    static async Task MainAsync(string[] args)
    {
        var circuitBreaker = Policy
            .Handle<Exception>()
            .CircuitBreakerAsync(
                3, // ConsecutiveExceptionsAllowedBeforeBreaking,
                TimeSpan.FromSeconds(5) // DurationOfBreak
            );

        Console.WriteLine("Circuit state before execution: " + circuitBreaker.CircuitState);

        await circuitBreaker.ExecuteAsync(() => Task.Delay(25));
        await circuitBreaker.ExecuteAsync(() => Task.Delay(25));
        await circuitBreaker.ExecuteAsync(() => { throw new System.Exception(); });
        await circuitBreaker.ExecuteAsync(() => Task.Delay(25));
        await circuitBreaker.ExecuteAsync(() => Task.Delay(25));

        Console.WriteLine("Circuit state after execution: " + circuitBreaker.CircuitState);
    } …
Run Code Online (Sandbox Code Playgroud)

c# task-parallel-library circuit-breaker async-await polly

4
推荐指数
1
解决办法
4902
查看次数

Polly 重试不会关闭现有的 HttpClient 调用

我使用 Polly 来处理一些场景,例如请求限制和超时。这些策略直接添加到 Startup.cs 中,如下所示:

var retries = //applying the retries, let say I set to 25 times with 10s delay. Total 250s.

serviceCollection
    .AddHttpClient<IApplicationApi, ApplicationApi>()
    .AddPolicyHandler((services, request) => GetRetryPolicy<ApplicationApi>(retries, services));
Run Code Online (Sandbox Code Playgroud)

政策:

static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy<T>(List<TimeSpan> retries, IServiceProvider services)
{
    return HttpPolicyExtensions
        .HandleTransientHttpError()
        .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.TooManyRequests)
        .WaitAndRetryAsync(retries,
            onRetry: (outcome, timespan, retryAttempt, context) =>
            {
                //do some logging
            }
}
Run Code Online (Sandbox Code Playgroud)

在 ApplicationApi.cs 中执行如下操作:

private readonly HttpClient _httpClient;
public ApplicationApi(HttpClient httpClient)
{
    _httpClient = httpClient;
}
       
public void CallApi()
{ 
      var …
Run Code Online (Sandbox Code Playgroud)

.net c# dotnet-httpclient .net-core polly

3
推荐指数
1
解决办法
2043
查看次数

使用 Polly.Net 的嵌套重试和断路器策略的意外行为

我编写了基于重试的弹性策略和熔断策略。现在可以工作,但其行为存在问题。

我注意到,当断路器打开half-open并且onBreak()事件再次执行以关闭电路时,会为重试策略触发一次额外的重试(这是状态的另一项the health verificationhalf-open

让我一步步解释:

我定义了两个用于重试和断路器的强类型策略:

static Policy<HttpResponseMessage> customRetryPolicy;
static Policy<HttpResponseMessage> customCircuitBreakerPolicy;

static HttpStatusCode[] httpStatusesToProcess = new HttpStatusCode[]
{
   HttpStatusCode.ServiceUnavailable,  //503
   HttpStatusCode.InternalServerError, //500
};
Run Code Online (Sandbox Code Playgroud)

重试策略的工作方式如下:每个请求两次 (2) 重试,每次重试之间等待五 (5) 秒。如果内部断路器打开,不得重试。仅重试 500 和 503 Http 状态。

customRetryPolicy = Policy<HttpResponseMessage>   

//Not execute a retry if the circuit is open
.Handle<BrokenCircuitException>( x => 
{
    return !(x is BrokenCircuitException);
})

//Stop if some inner exception match with BrokenCircuitException
.OrInner<AggregateException>(x =>
{
    return !(x.InnerException is BrokenCircuitException);
})

//Retry …
Run Code Online (Sandbox Code Playgroud)

c# circuit-breaker .net-core polly asp.net-core

2
推荐指数
1
解决办法
3503
查看次数