目前我有这个请求:
await url
.SetQueryParams(queryString)
.SetClaimsToken()
.GetJsonAsync<T>()
我现在想开始使用 Polly ( https://github.com/App-vNext/Polly ) 来处理重试并提供更好的用户体验。例如,由于网络连接不良,不会在第一次尝试时“挂断”用户。这是我尝试使用的示例:
int[] httpStatusCodesWorthRetrying = { 408, 500, 502, 503, 504 };
Policy
.Handle<HttpException>()
.OrResult<HttpResponse>(r => httpStatusCodesWorthRetrying.Contains(r.StatusCode))
.WaitAndRetryAsync(new[] {
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
})
.ExecuteAsync( await url... )
但它需要HttpResponse
为返回类型。从我的 Flurl 示例中可以看出,它返回 T
,即使它是一个 HttpResponse
。 T
只是用于反序列化 StringContent
的类型。
第一个示例根本不起作用,因为我在 PCL 中使用它并且我无法在那里获得对 System.Web
的引用。所以我尝试了这个:
Policy
.HandleResult(HttpStatusCode.InternalServerError)
.OrResult(HttpStatusCode.BadGateway)
.OrResult(HttpStatusCode.BadRequest)
.WaitAndRetryAsync(new[] {
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
})
.ExecuteAsync(async () =>
{
await url...
});
但这一个也不起作用,因为 Polly 期望 HttpStatusCode
作为返回类型。所以我的问题是:如何告诉 polly 处理那些 HttpStatusCode
并且仍然允许我返回 T
类型?
最佳答案
您不需要中断使用像 GetJsonAsync<T>()
这样的便捷方法,因为 Flurl 在非 2XX 响应(或者你 configure 它)上抛出异常,这应该允许它与 Polly 一起玩得很好。只需删除 .Handle<HttpException>
和 .OrResult<HttpResponse>
原始代码和句柄中的零件 FlurlHttpException
相反:
T poco = await Policy
.Handle<FlurlHttpException>(ex => httpStatusCodesWorthRetrying.Contains((int)ex.Call.Response.StatusCode))
.WaitAndRetryAsync(...)
.ExecuteAsync(() => url
.SetQueryParams(queryString)
.SetClaimsToken()
.GetJsonAsync<T>());
还有一个进一步清理的建议:
T poco = await Policy
.Handle<FlurlHttpException>(IsWorthRetrying)
.WaitAndRetryAsync(...)
.ExecuteAsync(() => url
.SetQueryParams(queryString)
.SetClaimsToken()
.GetJsonAsync<T>());
private bool IsWorthRetrying(FlurlHttpException ex) {
switch ((int)ex.Call.Response.StatusCode) {
case 408:
case 500:
case 502:
case 504:
return true;
default:
return false;
}
}
关于c# - 如何将 Polly 与 Flurl.Http 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40745809/