好问题。Flurl 为您提供了所有必要的钩子来执行此操作。首先定义一个DelegatingHandler
采用 Polly 策略的:
public class PollyHandler : DelegatingHandler
{
private readonly IAsyncPolicy<HttpResponseMessage> _policy;
public PollyHandler(IAsyncPolicy<HttpResponseMessage> policy) {
_policy = policy;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
return _policy.ExecuteAsync(ct => base.SendAsync(request, ct), cancellationToken);
}
}
然后创建一个自定义IHttpClientFactory
,返回您的自定义处理程序,并将默认处理程序作为其InnerHandler
:
public class PollyFactory : DefaultHttpClientFactory
{
private readonly IAsyncPolicy<HttpResponseMessage> _policy;
public PollyFactory(IAsyncPolicy<HttpResponseMessage> policy) {
_policy = policy;
}
public override HttpMessageHandler CreateMessageHandler() {
return new PollyHandler(_policy) {
InnerHandler = base.CreateMessageHandler()
};
}
}
最后,在应用启动时,定义您的策略并将其注册到 Flurl:
var policy = Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
.RetryAsync(5);
FlurlHttp.Configure(settings => settings.HttpClientFactory = new PollyFactory(policy));
一个重要的注意事项是,这种方法不适用于处理 FlurlHttpException 的策略。那是因为您在HttpMessageHandler
此处拦截呼叫。Flurl 将响应和错误转换为FlurlHttpException
更高的堆栈,因此这些不会被这种方法捕获/重试。上面示例中的策略会捕获HttpRequestException
和HttpResponseMessage
(使用非 2XX 状态代码),这将起作用。