首页 > 解决方案 > Polly 和 HttpClient 无限请求

问题描述

我尝试在HttpClient请求中使用 Polly。

这是我的代码:

    public static  async Task<ResponseWs> callAsync(int IdHeader)
    {
        ResponseWs w = new ResponseWs();
        w.retCode = 1;
        w.Message = "Errore Generico";

        httpcli = new HttpClient();
        ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

        getInbound(IdHeader, out int i, out string jsonObject, out string orderNum);
        url = String.Format(ConfigurationManager.AppSettings["XXXUrl"].ToString() + "charge?orderNum=" + orderNum);
        httpcli.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ConfigurationManager.AppSettings["XXXAuth"].ToString());
        httpcli.DefaultRequestHeaders.ConnectionClose = true;
        Logger.WriteInfo(url);
        Logger.WriteInfo(jsonObject);


        var retryPolicy = Policy
                .Handle<HttpRequestException>()
                .OrResult<HttpResponseMessage>(r => r.StatusCode != HttpStatusCode.OK)
                .WaitAndRetryAsync(maxRetryAttempts,  j=> pauseBetweenFailures, (result, timeSpan, retryCount, context) => {
                                Logger.WriteInfo($"Request failed with {result.Result.StatusCode}. Retry count = {retryCount}. Waiting {timeSpan} before next retry. ");
                            });

        try
        {
            var response = await retryPolicy.ExecuteAsync(async () =>
            {
                var cont = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
                var post = await httpcli.PostAsync("https://httpbin.org/status/400", cont).ConfigureAwait(false);
                return post;
            });

            if (response.IsSuccessStatusCode)
            {
                string responseContent = response.Content.ReadAsStringAsync().Result;

                XXXError sperr = JsonConvert.DeserializeObject<XXXError>(responseContent);

                if (sperr.status.ToUpper() == "OK")
                {
                    Logger.WriteInfo("OK");
                    w.retCode = 0;
                    w.Message = "OK";
                    return w;
                }
                else
                {
                    Logger.WriteError(responseContent);
                    Logger.WriteError(sperr.message);
                    w.retCode = 2;
                    w.Message = sperr.message;
                    return w;
                }
            }
            else
            {

                Logger.WriteError("Errore: " + response.StatusCode);
                Logger.WriteError(response.Content.ToString());
                w.retCode = 1;
                w.Message = "Errore Chiamata MW";
                return w;
            }
        }
        catch (AggregateException e)
        {
            foreach (Exception ie in e.InnerExceptions)
            {
                Logger.WriteError(ie.GetType().Name + ":" + ie.Message);
                Logger.WriteError(e.InnerException.Message);
            }
            w.retCode = 1;
            w.Message = "Errore Chiamata MW";
            return w;
        }
        catch (HttpRequestException e)
        {
            Logger.WriteError(e.Message);
            Logger.WriteError(e.InnerException.Message);
            w.retCode = 1;
            w.Message = "Errore Chiamata MW";
            return w;
        }
        catch (Exception ex)
        {
            Logger.WriteError(ex.Message);
            Logger.WriteError(ex.InnerException.Message);
            w.retCode = 1;
            w.Message = "Errore Chiamata MW";
            return w;
        }
    }

我的日志报告:

Request failed with BadRequest. Retry count = 3. Waiting 00:00:10 before next retry. 
Request failed with BadRequest. Retry count = 2. Waiting 00:00:10 before next retry. 
Request failed with BadRequest. Retry count = 1. Waiting 00:00:10 before next retry.

但请求仍然未决,我必须手动强制关闭。

问题出在哪里?

标签: c#polly

解决方案


代码正在等待由 发出的单个 HTTP 调用的结果httpClient.PostAsync("https://httpbin.org/status/400", null);,而不是调用本身。结果,它重试读取该结果,而不是重试调用。如果post.Wait();抛出,代码将继续重试并重新抛出相同的异常。

重试的代码应该retryPolicy.ExecuteAsync调用中:

 var response = await retryPolicy.ExecuteAsync(async () =>
    {
        var res=await httpClient.PostAsync("https://httpbin.org/status/400", null);
        return res;
    });

甚至 :

var response = await retryPolicy.ExecuteAsync(()=> 
                          httpClient.PostAsync("https://httpbin.org/status/400",
                          null));

使用问题的代码是:

var response = await retryPolicy.ExecuteAsync(async ()=> {

    var cont = new StringContent(jsonObject.ToString(), Encoding.UTF8, "application/json");
    var post = await httpcli.PostAsync(url, cont);
    return post;
});

推荐阅读