我正在使用Polly框架进行瞬态故障处理。对于同步操作,Polly断路器策略工作正常,但是当我创建其异步版本时,它不会重试执行。请建议:
异步方法:
private async static Task HelloWorld()
{
if (DateTime.Now < programStartTime.AddSeconds(10))
{
Console.WriteLine("Task Failed.");
throw new TimeoutException();
}
await Task.Delay(TimeSpan.FromSeconds(1));
Console.WriteLine("Task Completed.");
}
Polly断路器异步策略:
private static void AsyncDemo3(Func<Task> action)
{
programStartTime = DateTime.Now;
Policy policy = Policy
.Handle<TimeoutException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(2));
try
{
var a = policy.ExecuteAndCaptureAsync(action, true).GetAwaiter().GetResult();
}
catch (AggregateException ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
}
执行Polly断路器政策:
AsyncDemo3(HelloWorld的);
请帮助找到并解决问题。
答案 0 :(得分:12)
我相信你误解了断路器政策的作用。
它的作用是,如果你调用它给定的次数并且每次都失败,那么它将停止调用给定的方法一段时间。但它本身并没有重试。
为了做我认为你想做的事情,你需要将重试策略与断路器策略结合起来。一种方法是:
Policy retryPolicy = Policy.Handle<TimeoutException>().RetryAsync(3);
Policy circuitBreakerPolicy = Policy
.Handle<TimeoutException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(2));
try
{
retryPolicy.ExecuteAsync(() => circuitBreakerPolicy.ExecuteAsync(action, true))
.GetAwaiter().GetResult();
}
…
此代码的输出为:
Task Failed.
Task Failed.
Task Failed.
Exception: The circuit is now open and is not allowing calls.
答案 1 :(得分:1)
建议如下创建两个策略并使用PolicyWrap对其进行组合。
政策创建
var circuitBreakerPolicy = Policy
.Handle<TimeoutException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(2));
var retryPolicy = Policy.Handle<TimeoutException>().RetryAsync(3);
// Combined policy: outermost first, innermost last
var policy = Policy.WrapAsync(retryPolicy, circuitBreakerPolicy);
政策用法
await this.policy.ExecuteAsync(async () => await SomeFooMethodAsync(cancellationToken));