You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 15:38:14