【问题标题】:Starting with Polly basics从 Polly 基础知识开始
【发布时间】:2021-01-18 18:12:47
【问题描述】:

我对 Polly 很陌生,我正在尝试从最基础的开始了解其工作原理。

为了测试重试次数,我尝试创建一个有 33% 的代码(打印)以生成 DivideByZeroException。生成错误时,它会上升到 policy.Execute 似乎不由 Polly 管理。

有人可以帮我调整这段代码吗?我正在使用 .Net Framework 4.7.2。

using System;
using Polly;

class Program
{
    static void Main(string[] args)
    {
        var policy = Policy
                        .Handle<DivideByZeroException>()
                        .Retry();

        policy.Execute(() => Print());
        Console.ReadKey();
    }

    private static void Print()
    {
        var rand = new Random();
        int a = rand.Next(1000, 2000);
        int b = rand.Next(0, 2);
        Console.WriteLine("a = {0} - b {1}", a, b);
        int c = a / b;
        Console.WriteLine("c = {0}", c);
    }
}

【问题讨论】:

  • 你能举一个例子来说明你看到的和你期望看到的吗?请注意,由于您使用的是Random,因此实际上可能不会发生异常。
  • 尝试将Random 作为单个静态变量创建一次,而不是每次Print 运行时都创建一个新的Random

标签: c# transient polly retry-logic resiliency


【解决方案1】:

如果你设置b = 0,而不是使用Random,你会看到它正在处理异常,但它不会永远重试——你会看到它在失败前打印输出两次。所以这意味着,在使用Random 的情况下,它有时 连续多次将b 设置为0,在这种情况下,策略会耗尽其重试次数,因此它会抛出。

您可以使用Retry(n) 配置策略以增加重试次数。或者,您可以使用RetryForever()

如果您不希望您的调用代码在重试用尽时抛出,您可以改用捕获结果:

var result = policy.ExecuteAndCapture(() => Print());
if (result.Outcome == OutcomeType.Failure)
{
    // result.FinalException contains the exception
}

【讨论】:

  • 感谢您的回复...与 .Retry(1) 似乎有效...我认为 .Retry() 就像 Retry(1) 但似乎我错了。
  • @user1812102 Retry()Retry(1) 相同。你设置b = 0了吗?如果没有,您只是用Random 掷骰子来判断它是否有效。
  • 也许我在看到错误后的输出时感到困惑,无论如何现在看起来很清楚......