介绍
本节我们来介绍一款强大的库Polly,Polly是一种.NET弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢复等策略。 Polly针对对.NET 4.0,.NET 4.5和.NET Standard 1.1以及.NET Core实现,该项目作者现已成为.NET基金会一员,项目一直在不停迭代和更新,项目地址【https://github.com/App-vNext/Polly】,你值得拥有。接下来我们以.NET Framework 4.5来演示它的强大功能。
重试策略(Retry)
重试策略针对的前置条件是短暂的故障延迟且在短暂的延迟之后能够自我纠正。允许我们做的是能够自动配置重试机制。
class Program
{
static void Main(string[] args)
{
try
{
var retryTwoTimesPolicy =
Policy
.Handle<DivideByZeroException>().
Or<AggregateException>() //多种异常
.Retry(3, (ex, count) =>
{
Console.WriteLine("执行失败! 重试次数 {0}", count);
Console.WriteLine("异常来自 {0}", ex.GetType().Name);
});
retryTwoTimesPolicy.Execute(() =>
{
Compute();
});
}
catch (DivideByZeroException e)
{
Console.WriteLine($"Excuted Failed,Message: ({e.Message})");
}
Console.Read();
}
static int Compute()
{
var a = 0;
return 1 / a;
}
}
class Program
{
static void Main(string[] args)
{
try
{
//隔一段时间重试
var politicaWaitAndRetry = Policy
.Handle<DivideByZeroException>()
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(3),
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(7)
}, ReportaError);
politicaWaitAndRetry.Execute(() =>
{
Compute();
});
}
catch (DivideByZeroException e)
{
Console.WriteLine($"Excuted Failed,Message: ({e.Message})");
}
Console.Read();
}
static int Compute()
{
var a = 0;
return 1 / a;
}
/// <summary>
/// 异常信息
/// </summary>
/// <param name="e"></param>
/// <param name="tiempo"></param>
/// <param name="intento"></param>
/// <param name="contexto"></param>
static void ReportaError(Exception e, TimeSpan tiempo, int intento, Context contexto)
{
Console.WriteLine($"异常: {intento:00} (调用秒数: {tiempo.Seconds} 秒)\t执行时间: {DateTime.Now}");
}
}
回退(Fallback)
操作仍然会失败,也就是说当发生这样的事情时我们打算做什么。也就是说定义失败返回操作。
class Program
{
static void Main(string[] args)
{
try
{
var fallBackPolicy =
Policy<string>
.Handle<DivideByZeroException>()
.Fallback("执行失败,返回Fallback");
//运行异常时,设置默认值
var fallBack = fallBackPolicy.Execute(Compute);
Console.WriteLine(fallBack);
}
catch (DivideByZeroException e)
{
Console.WriteLine($"Excuted Failed,Message: ({e.Message})");
}
Console.Read();
}
static string Compute()
{
var a = 0;
a = 1 / a;
return "无异常时函数";
}
}