我在我的 UWP 应用程序中使用 Refit 客户端和用于依赖注入的 Polly 策略设置了以下服务集合:
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 响应的 StatusCode 为 401(在我使用的 API 中意味着会话已过期)时,应用程序会检查凭据是否已存储在我的应用程序中(在我的应用程序中,在登录阶段我可以选择是否这样做是不保存凭据的临时会话)或不。
如果存储了凭据,Polly 策略可以继续重试请求。
但我希望在未存储凭据的情况下,策略不执行重试而是关闭应用程序。
有没有办法告诉 Polly 策略在处理特定的 http 事件时有条件地执行重试,而不需要任何技巧?
HandleResult
可以接受返回 true
或 false
(Func<T, bool>
) 的同步委托,这就是为什么您可以结合状态代码和凭证检查
Policy<HttpResponseMessage>
.HandleResult(r =>
r.StatusCode == HttpStatusCode.Unauthorized
&& new CredUtils().GetCredentialFromLocker() != null)
.RetryAsync(1, (_, count) => Debug.WriteLine("Retry {0} times", count));
更新#1
但是如果凭证检查为空,我如何在策略中执行代码(在我的情况下关闭应用程序)?
由于您已经对整个
HttpClient
应用了重试逻辑(作为引擎盖下的DelegatingHandler
),这就是为什么您不应该尝试从策略中退出应用程序的原因。
更好的方法可能是从策略或
GetCredentialFromLocker
中抛出自定义异常,并使用 try-catch 包装您的改装客户端调用,以通过退出应用程序来处理该异常。
PolicyRegistry
(而不是在 HttpClient
上),那么您还有另一个选择。 ExecuteAsync
可以接收一个 Context
对象,您可以在策略中对其进行操作。所以,如果 GetCredentialFromLocker
方法调用返回 null
那么你就在上下文中设置了一个“标志”。在 ExecuteAsync
调用之后,您可以评估上下文并在需要时退出应用程序。