c# - 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.
但请求仍然未决,我必须手动强制关闭。
问题出在哪里?
解决方案
代码正在等待由 发出的单个 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;
});
推荐阅读
- ios - 在 UICollectionView 中拖动行和列
- robotframework - 在远程主机上的命名空间内运行守护程序。(机器人框架)
- python - 我为脚本多次工作做错了吗?
- java - JPA。过滤字段 Set<> 包含特定值的实体
- python - 在 python 中计算重复项。为什么我们应该只取 set 而不是 list 或 dict?
- bash - 让 gitlab 工作不等待“脚本”部分的任何返回
- python - 在数据python中用nans计算3个数组的加权平均值
- javascript - 方法测量模拟期间代理未使用的时间
- c# - 我想在 C# 表单应用程序的列表框中打印 C++ 向量的元素
- python - 如何在 Paramiko 库中配置首选密码