如何解决C# 中的 Polly 模式用于工作流? CallApi 成功CallApi 失败CallApi 超时和 CallAnotherApi 成功CallApi 超时和 CallAnotherApi 失败
两种 API 方法具有相同类型的结果。 我想通过波利政策来实现这一点。
这是我的示例代码:
var retryPolicy = Policy
.Handle<HttpRequestException>(ex => ex.StatusCode == HttpStatusCode.RequestTimeout)
.RetryAsync(1,async (exception,retryCount) =>
await CallAnotherAPI());
var fallbackPolicy = Policy<HttpResponseMessage>
.Handle<Exception>()
.FallbackAsync((r,c,ct) => throw r.Exception,async (r,c) =>
{
Log(r.Message);
});
var result = await fallbackPolicy
.WrapAsync(retryPolicy)
.ExecuteAsync(async () =>
{
await CallAPI();
});
但它不起作用并且一直执行 fallbackPolicy。如何编写如果 retryPolicy 为真,则不会执行 fallbackPolicy 的代码?
解决方法
如果我正确理解您的工作流程,那么您根本不需要重试策略。回退策略就足够了。
所以,假设 CallApi
和 CallAnotherApi
是这样实现的:
private static HttpClient client = new HttpClient();
public static async Task<HttpResponseMessage> CallAPI()
{
return await client.GetAsync("http://httpstat.us//408");
}
public static async Task<HttpResponseMessage> CallAnotherAPI()
{
var response = await client.GetAsync("http://httpstat.us//500");
response.EnsureSuccessStatusCode();
return response;
}
- 我使用
httpstatus.us
来模拟某些 http 状态代码 -
CallApi
将始终因请求超时而失败 -
CallAnotherApi
将始终抛出HttpRequestException
,因为Ensure
方法调用
现在让我们看看策略定义和用法:
public static async Task Main(string[] args)
{
var fallbackPolicy = Policy<HttpResponseMessage>
.HandleResult(msg => msg.StatusCode == HttpStatusCode.RequestTimeout)
.FallbackAsync(async (_) => await CallAnotherAPI());
HttpResponseMessage result;
try
{
result = await fallbackPolicy
.ExecuteAsync(async () =>
{
return await CallAPI();
});
}
catch (Exception ex) {
Console.WriteLine(ex.Message); //TODO: replace with logging
throw;
}
Console.WriteLine(result.StatusCode);
}
- 仅当响应的状态代码为 408 时才应触发回退策略
-
ExecuteAsync
将抛出异常,如果CallApi
或CallAnotherApi
抛出
让我们一一看看不同的场景
CallApi
成功
public static async Task<HttpResponseMessage> CallAPI()
{
return await client.GetAsync("http://httpstat.us//200");
}
输出
OK
CallApi
失败
public static async Task<HttpResponseMessage> CallAPI()
{
var response = await client.GetAsync("http://httpstat.us//500");
response.EnsureSuccessStatusCode();
return response;
}
输出
Response status code does not indicate success: 500 (Internal Server Error).
然后应用程序因为throw;
CallApi
超时和 CallAnotherApi
成功
public static async Task<HttpResponseMessage> CallAPI()
{
return await client.GetAsync("http://httpstat.us//408");
}
public static async Task<HttpResponseMessage> CallAnotherAPI()
{
var response = await client.GetAsync("http://httpstat.us//200");
response.EnsureSuccessStatusCode();
return response;
}
输出
OK
CallApi
超时和 CallAnotherApi
失败
public static async Task<HttpResponseMessage> CallAPI()
{
return await client.GetAsync("http://httpstat.us//408");
}
public static async Task<HttpResponseMessage> CallAnotherAPI()
{
var response = await client.GetAsync("http://httpstat.us//500");
response.EnsureSuccessStatusCode();
return response;
}
输出
Response status code does not indicate success: 500 (Internal Server Error).
然后应用程序因为throw;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。