目前我有这个要求:
await url
.SetQueryParams(queryString)
.SetClaimsToken()
.GetJsonAsync<T>()
Run Code Online (Sandbox Code Playgroud)
我现在想开始使用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... )
Run Code Online (Sandbox Code Playgroud)
但它需要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...
});
Run Code Online (Sandbox Code Playgroud)
但是这个也不起作用,因为Polly期望HttpStatusCode作为回归类型.所以我的问题是:我如何告诉polly处理那些HttpStatusCode并仍允许我返回类型T?
如果 HTTP 调用失败,我在非常基本的场景中使用 Polly 进行指数退避:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return await HandleTransientHttpError()
.Or<TimeoutException>()
.WaitAndRetryAsync(4, retryAttempt => TimeSpan.FromSeconds(Math.Pow(3, retryAttempt)))
.ExecuteAsync(async () => await base.SendAsync(request, cancellationToken).ConfigureAwait(false));
}
private static PolicyBuilder<HttpResponseMessage> HandleTransientHttpError()
{
return Policy
.HandleResult<HttpResponseMessage>(response => (int)response.StatusCode >= 500 || response.StatusCode == System.Net.HttpStatusCode.RequestTimeout)
.Or<HttpRequestException>();
}
Run Code Online (Sandbox Code Playgroud)
我有一个测试 API,它只是HttpListener在while(true). 目前,我正在尝试测试客户端在每次调用收到 500 时是否正确重试。
while (true)
{
listener.Start();
Console.WriteLine("Listening...");
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
response.StatusCode = (int)HttpStatusCode.InternalServerError;
//Thread.Sleep(1000 * 1); …Run Code Online (Sandbox Code Playgroud)