[英]Polly patterns in C# for a workflow?
我有一个这样的工作流程:
两种 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
将始终因请求超时而失败Ensure
方法, CallAnotherApi
将始终抛出HttpRequestException
现在让我们看看策略定义和用法:
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);
}
CallApi
或CallAnotherApi
抛出异常,则ExecuteAsync
将抛出异常让我们一一看看不同的场景
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;
崩溃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;
崩溃throw;
在这种情况下,polly 回退就足够了。 像这样....
var fallbackPolicy = Policy<HttpResponseMessage>
.Handle<Exception>()
.FallbackAsync((r, c, ct) => throw r.Exception,
async (r, c) =>
{
Log(r.Message);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.