[聚合文章] Polly简介 — 3. 执行策略

.Net 2018-01-06 25 阅读

执行策略

执行策略的常见方式是调用策略的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 );

具体示例在介绍弹性策略的超时策略时有介绍到。

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。