【问题标题】:Stop Execution on certain condition on Polly 4.3Polly 4.3 在特定条件下停止执行
【发布时间】:2022-10-19 13:51:28
【问题描述】:

我们开始在我们遗留的 WinForms 项目中使用 Polly 库,该项目仍然在 .NET 4.0 框架上运行(这是必需的)。

问题是我们必须使用 Polly 库的 4.3 版本,并且很难找到问题的解决方案,因为我们找到的所有文档都是关于该库的更新版本。

例如,我们不能从重试回调传递Context 值来执行,因为Context 是只读的,我们不能传递参数来执行委托,因为它使用Action 类型。

对于所有这些问题,我们已经找到了创造性的解决方案,但我们仍然无法找到在特定条件下停止执行的方法。

在 Polly 5 中,为此目的引入了CancellationToken,但我想在以前的版本中也有办法强制停止重试。

public RetryPolicy DevicePolicy => Policy
    .Handle<Exception>()
    .WaitAndRetry(
        MaxRetries,
        retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
        (exception, timeSpan, retryCount, context) =>
    {
        //If i get the timeout exception i want to stop the execution
        if (exception is TimeoutException)
        {
            //In Polly 5.0 I can set the cancellationToken but with 4.3 there isn't
            var cts = context["CancellationTokenSource"] as CancellationTokenSource;
            cts.Cancel();
        }
        else
        {
            var errHeader = $"device connection error. Attempt {retryCount} of {MaxRetries}";
            Log.Warn(errHeader, exception);
        }
    });

任何想法?

【问题讨论】:

    标签: c# .net-4.0 polly cancellation-token retry-logic


    【解决方案1】:

    我认为您试图从错误的角度解决问题。

    与其尝试取消重试,不如尝试避免触发重试。

    我创建了一个sample application in dotnetfiddle 以确保我提出的解决方案也适用于 Polly 4.3 版

    public static void Main()
    {
        var retry = Policy
            .Handle<Exception>(ex => !(ex is TimeoutException))
            .WaitAndRetry(2, _ => TimeSpan.FromSeconds(1));
        
        retry.Execute(WrappedMethod);
    }
    
    public static int counter = 0;
    public static void WrappedMethod()
    {
        Console.WriteLine("The wrapped method is called");
        if(counter++ == 1) 
            throw new TimeoutException();
        throw new ArgumentException();
    }
    

    Handle&lt;TException&gt; 方法有 an overload 接受委托 (Func&lt;Exception, bool&gt;)。换句话说,您可以定义一个谓词,您可以在其中定义哪些异常应该触发重试。

    根据我的理解,您希望在每种情况下都执行重试,除非抛出 TimeoutException。您可以像这样轻松地指定它:

    .Handle<Exception>(ex => !(ex is TimeoutException))
    

    【讨论】:

    • 是的,这就是我正在寻找的解决方案!我在想如何才能捕获所有执行,除了超时,但我不知道该怎么做,现在我有了解决方案!非常感谢明天在办公室我会努力的!
    • @MicheleMassari 你有时间检查吗?
    • 它就像一个魅力......再次感谢您的宝贵帮助......
    猜你喜欢
    • 2019-12-17
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多