执行策略的常见方式是调用策略的Execute函数
var policy = Policy.Handle<TimeoutException>().Retry();
policy.Execute(DoSomething);
返回值:
如果有返回值,它也是可以获取其返回值的:
var result = policy.Execute(DoSomething);
捕获异常:
如果在策略的执行过程中出现了异常,也会在该函数中同步抛出来,和直接执行该委托行为一致。可以直接通过try-catch处理。
try
{
policy.Execute(DoSomething);
}
catch (Exception e)
{
throw;
}
也可以通过ExecuteAndCapture
函数捕获异常。
var result = policy.ExecuteAndCapture(DoSomething);
if (result.FaultType == null)
{
Console.WriteLine(result.Result);
}
策略上下文
在策略的处理过程中,有一个上下文对象,可以在回调函数中使用:
public static RetryPolicy Retry(this PolicyBuilder policyBuilder, int retryCount, Action<Exception, int, Context> onRetry);
它是一个IDictionary<string, object>类型的对象,它在Policy的执行过程中都可以使用,如:
Policy.Handle<TimeoutException>().Retry(3, (err, countDown, context) =>
{
var method = context["method"];
ConsoleLogger.WriteLine(method);
})
这个上下文对象可以在应用策略的时候带入:
policy.Execute(DoSomething, new Context("context")
{
["method"] = "PolicyTest"
});
依赖注入
Polly也自带了一个简单的DI框架,方便复用Policy,使用方式如下:
var registry = new PolicyRegistry();
registry.Add("timeout & retry", Policy.Handle<TimeoutException>().Retry(3));
var policy = registry.Get<ISyncPolicy>("timeout & retry");
policy.Execute(DoSomething);
当然,也可以使用Autofac等自己喜欢的方式。
线程安全Policy本身是线程安全的,可以并发使用同一个Policy,但如果Policy中执行的委托有多线程问题,仍然会出现异常。
异步的支持Policy对异步操作也提供了良好的支持,只需要使用相应以Async结尾的函数即可。
var policy = Policy.Handle<TimeoutException>().RetryAsync(3);
await policy.ExecuteAsync(DoSomethingAsync);
PS:有的不需要(也没有)以Async的函数,如Handle
同步上下文对于有的异常处理,如果需要同步上下文,则需要在ExecuteAsync函数中设置continueOnCapturedContext参数为false。
var policy = Policy.Handle<TimeoutException>().RetryAsync(3);
await policy.ExecuteAsync(DoSomethingAsync, CancellationToken.None, continueOnCapturedContext: true);
Cancellation的支持
Polly也支持系统的co-operative cancellation框架,在重试,超时,bulkhead等策略中通知执行的委托,从而影响其行为。要使用Cancellation,需要在Excute的时候传入CancellationToken。
policy.Execute(ct =>
{
ct.ThrowIfCancellationRequested();
}, cts.Token);
具体示例在介绍弹性策略的超时策略时有介绍到。
到此这篇关于Polly实现执行策略的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持易知道(ezd.cc)。