如何在UWP中通过Polly实现Refit请求的有条件重试?
问题描述
在UWP应用的依赖注入中配置了包含Refit客户端与Polly策略的ServiceCollection,代码如下:
var serviceCollection = new ServiceCollection(); serviceCollection .AddRefitClient(typeof(IClassevivaAPI)) .ConfigureHttpClient( (sp, client) => { client.BaseAddress = new Uri(Endpoint.CurrentEndpoint); } ) .AddPolicyHandler( Policy<HttpResponseMessage> .HandleResult(r => r.StatusCode == System.Net.HttpStatusCode.Unauthorized) .RetryAsync( 1, async (ex, count) => { Debug.WriteLine("Retry {0} times", count); var loginCredentials = new CredUtils().GetCredentialFromLocker(); if (loginCredentials != null) { //the retry can continue } } ) );
需求:当HTTP响应状态码为401(API会话过期)时,检查是否存储了登录凭据(存在不保存凭据的临时会话场景)。若有凭据则执行Polly重试;若无凭据则不重试,直接关闭应用。需要一种非hack的实现方式。
解决方案
步骤1:注册凭据工具类到DI容器
先将CredUtils注册到ServiceCollection,遵循依赖注入原则,避免硬编码实例化:
serviceCollection.AddSingleton<CredUtils>();
步骤2:使用带条件判断的Polly重试策略
替换原有的RetryAsync调用,利用Polly提供的重载方法,通过shouldRetryAsync委托实现条件重试:
.AddPolicyHandler((sp) => Policy<HttpResponseMessage> .HandleResult(r => r.StatusCode == System.Net.HttpStatusCode.Unauthorized) .RetryAsync( 1, // 重试前的回调逻辑(可选,比如刷新令牌) async (result, retryCount) => { Debug.WriteLine("Retry {0} times", retryCount); var credUtils = sp.GetRequiredService<CredUtils>(); var loginCredentials = credUtils.GetCredentialFromLocker(); if (loginCredentials != null) { // 执行重试前的必要操作,例如重新获取有效令牌 // ... } }, // 重试条件判断委托 async (result, retryCount) => { var credUtils = sp.GetRequiredService<CredUtils>(); var loginCredentials = credUtils.GetCredentialFromLocker(); if (loginCredentials == null) { // 无存储凭据,直接关闭应用 Application.Current.Exit(); return false; } // 有凭据,允许执行重试 return true; } ) );
核心逻辑说明
shouldRetryAsync委托是实现条件重试的核心:每次触发重试前会调用该方法,返回true则执行重试,返回false则终止策略流程。- 通过DI容器获取
CredUtils实例,而非直接new,提升代码的可维护性和可测试性。 - 当检测到无存储凭据时,直接调用
Application.Current.Exit()关闭应用,同时返回false终止重试。
内容的提问来源于stack exchange,提问作者Gabboxl
相关产品推荐
相关产品推荐

