C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C# Polly库捕捉异常

C#调用Polly库实现捕捉异常处理的操作代码

作者:一个专注写bug的小白猿

Polly 是一个 .NET 弹性和瞬态故障处理库,允许开发人员以 Fluent 和线程安全的方式来实现重试、断路、超时、隔离和回退策略,本文给大家介绍了C#调用Polly库实现捕捉异常处理操作,文中有详细的代码示例供大家参考,需要的朋友可以参考下

一、Polly介绍

官方对 Polly 的介绍是这样的:

Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.

翻译过来大概意思是:Polly 是一个 .NET 弹性和瞬态故障处理库,允许开发人员以 Fluent 和线程安全的方式来实现重试、断路、超时、隔离和回退策略。

二、Polly 的七种策略

Polly 可以实现重试、断路、超时、隔离、回退和缓存策略

1、重试(Retry)

出现故障自动重试

//捕捉到错误,自动重试三次
Policy.Handle<Exception>()
 .Retry(3, (exception, retryCount) =>
 {
     Console.WriteLine(DateTime.Now + $"代码异常: {exception},开始第 {retryCount} 次重试。");
 });

2、 断路(Circuit-breaker)

当系统遇到严重问题时,快速回馈失败比让用户/调用者等待要好,限制系统出错的体量,有助于系统恢复。比如,当我们去调一个第三方的 API,有很长一段时间 API 都没有响应,可能对方服务器瘫痪了。如果我们的系统还不停地重试,不仅会加重系统的负担,还会可能导致系统其它任务受影响。所以,当系统出错的次数超过了指定的阈值,就要中断当前线路,等待一段时间后再继续。

//捕捉到同一个异常两次时,就停下来,等待 1 分钟后再继续
Policy.Handle<SomeException>()    
.CircuitBreaker(2, TimeSpan.FromMinutes(1));

3、 超时(Timeout)

当系统超过一定时间的等待,我们就几乎可以判断不可能会有成功的结果。比如平时一个网络请求瞬间就完成了,如果有一次网络请求超过了 30 秒还没完成,我们就知道这次大概率是不会返回成功的结果了。因此,我们需要设置系统的超时时间,避免系统长时间做无谓的等待。

//这里设置了超时时间不能超过 30 秒,否则就认为是错误的结果,并执行回调
Policy.Timeout(30, onTimeout: (context, timespan, task) => 
{   
    Console.WriteLine("30秒无响应,需要执行的逻辑");
});

4、 隔离(Bulkhead Isolation)

当系统的一处出现故障时,可能促发多个失败的调用,很容易耗尽主机的资源(如 CPU)。下游系统出现故障可能导致上游的故障的调用,甚至可能蔓延到导致系统崩溃。所以要将可控的操作限制在一个固定大小的资源池中,以隔离有潜在可能相互影响的操作。

//这个策略是最多允许 10 个线程并发执行,如果执行被拒绝,则执行回调
Policy.Bulkhead(10, context => 
{   
     Console.WriteLine("当前线程超过10个,需要执行的逻辑");
});

5、 回退(Fallback)

有些错误无法避免,就要有备用的方案。这个就像浏览器不支持一些新的 CSS 特性就要额外引用一个 polyfill 一样。一般情况,当无法避免的错误发生时,我们要有一个合理的返回来代替失败。

//当用户没有填写名称时,我们就给他一个默认名称,这种策略可以这样定义:
Policy.Handle<Whatever>()   
.Fallback<User>(() => User.GetDefaultName())

6、 缓存(Cache)

一般我们会把频繁使用且不会怎么变化的资源缓存起来,以提高系统的响应速度。如果不对缓存资源的调用进行封装,那么我们调用的时候就要先判断缓存中有没有这个资源,有的话就从缓存返回,否则就从资源存储的地方(比如数据库)获取后缓存起来,再返回,而且有时还要考虑缓存过期和如何更新缓存的问题。Polly 提供了缓存策略的支持,使得问题变得简单。

//这是官方的一个使用示例用法,
//它定义了缓存 5 分钟过期的策略,然后把这个策略应用在指定的 Key(即 `FooKey`)上。
var memoryCacheProvider = new MemoryCacheProvider(myMemoryCache); 
var cachePolicy = Policy.Cache(memoryCacheProvider, TimeSpan.FromMinutes(5)); 
TResult result = cachePolicy.Execute(context => getFoo(), new Context("FooKey"));

7、 策略包(Policy Wrap)

一种操作会有多种不同的故障,而不同的故障处理需要不同的策略。这些不同的策略必须包在一起,作为一个策略包,才能应用在同一种操作上。也就是 Polly 的弹性,即各种不同的策略能够灵活地组合起来。

//先是把预先定义好的多种不同的策略包在一起,作为一个整体策略,然后应用在同一个操作上。
var policyWrap = Policy  
.Wrap(fallback, cache, retry, breaker, timeout, bulkhead); 
policyWrap.Execute(() =>
{
    Console.WriteLine("多种策略共同执行的逻辑");
});

三、简单代码示例

备注:先引入Nuget包(Polly)

 //创建一个策略,用于处理异常,并进行重试
 public static Policy policy = Policy.Handle<Exception>()
 .Retry(3, (exception, retryCount) =>
 {
     Console.WriteLine(DateTime.Now + $"代码异常: {exception},开始第 {retryCount} 次重试。");
 });
 
 
  public async Task Execute()
  {
     //重试机制
     policy.Execute(() =>  //这里接收一个委托方法,也就是捕捉到异常之后要执行的业务逻辑
     {
         Console.WriteLine("重试");
     });
  }
  

以上就是C#调用Polly库实现捕捉异常处理的操作代码的详细内容,更多关于C# Polly库捕捉异常的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文