简体   繁体   English

Polly 4.3 在特定条件下停止执行

[英]Stop Execution on certain condition on Polly 4.3

We started using the Polly library in our legacy WinForms project which still runs on the .NET 4.0 framework (is a requisite).我们开始在我们遗留的 WinForms 项目中使用 Polly 库,该项目仍然在 .NET 4.0 框架上运行(是必需的)。

The problem is that we have to use version 4.3 of the Polly library and it is difficult to find solutions to the problems because all the documentation we find is about more recent versions of the library.问题是我们必须使用 Polly 库的 4.3 版本,并且很难找到问题的解决方案,因为我们找到的所有文档都是关于该库的更新版本。

For example we can't pass Context values from retry callback to execute because Context is readonly and we can't pass parameters to execute delegate because it use an Action type.例如,我们不能将重试回调中的Context值传递给执行,因为Context是只读的,并且我们不能将参数传递给执行委托,因为它使用Action类型。

To all these problems we have find a creative solution but we can't still found a way to stop the execution on certain condition.对于所有这些问题,我们已经找到了创造性的解决方案,但我们仍然无法找到在特定条件下停止执行的方法。

In Polly 5, CancellationToken was introduced for this purpose but I guess there were ways to force the retry to stop in previous versions as well.在 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);
        }
    });

Any Idea?任何想法?

I think you have tried to solve the problem from the wrong angle.我认为您试图从错误的角度解决问题。

Rather than trying to cancel a retry, try to avoid triggering the retry.与其尝试取消重试,不如尝试避免触发重试。

I've created a sample application in dotnetfiddle to make sure that my proposed solution work with Polly version 4.3 as well在 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();
}

The Handle<TException> method has an overload which accepts a delegate ( Func<Exception, bool> ). Handle<TException>方法有一个接受委托( Func<Exception, bool>的重载 In other words you can define a predicate where you can define which exceptions should trigger a retry.换句话说,您可以定义一个谓词,您可以在其中定义哪些异常应该触发重试。

According to my understanding you want to perform a retry in each and every case except when a TimeoutException is thrown.根据我的理解,除了抛出TimeoutException之外,您希望在每种情况下都执行重试。 You can specify this really easily like this:您可以像这样轻松地指定它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM