gpt4 book ai didi

c# - Polly 重试除特定条件外的所有异常

转载 作者:行者123 更新时间:2023-12-03 17:32:46 25 4
gpt4 key购买 nike

Polly 中是否有办法重试除指定异常之外的所有异常。例如:

var p = Policy
.Handle<HttpListenerException>(e => !(e.NativeErrorCode == 1))
.Or<Exception>()
.RetryAsync();

在这里,我选择了一个稍微做作的情况,我想 不是 NativeErrorCode == 1 时重试?

我最初希望如果有任何非 1 的值,以及由 .Or<Exception>() 处理的任何其他异常,这将重试。 ..

实际发生的是 .Or<Exception>还将捕获 NativeErrorCode == 1 ,即使它被排除在上面?我认为..

我考虑过的一个选项,但没有经过测试......(没有错误检查;p)
var p = Policy
.Handle<Exception>(e => SomethingMoreComplex(e) == true)
.RetryAsync();

private bool SomethingMoreComplex(Exception e)
{
if (e is HttpListenerException t)
{
if (t.NativeErrorCode == 1) return false;
}

return true;
}

那是线程安全的吗? :|

最佳答案

如果您查看 Policy.HandleSyntax.cs文件然后你可以看到Handle<T>方法已定义:

public partial class Policy
{
public static PolicyBuilder Handle<TException>() where TException : Exception
=> new PolicyBuilder(exception => exception is TException ? exception : null);

public static PolicyBuilder Handle<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception
=> new PolicyBuilder(exception => exception is TException texception && exceptionPredicate(texception) ? exception : null);

...
}

public partial class Policy<TResult>
{
public static PolicyBuilder<TResult> Handle<TException>() where TException : Exception
=> new PolicyBuilder<TResult>(exception => exception is TException ? exception : null);

public static PolicyBuilder<TResult> Handle<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception
=> new PolicyBuilder<TResult>(exception => exception is TException texception && exceptionPredicate(texception) ? exception : null);

...
}
  • 所有方法都依赖于 PolicyBuilder类,它有一个 internal ctor .
  • 所以,我们不能在我们的自定义代码中使用它。

  • 另请注意 Policy类(class) does not a public ctor .
  • 所以,我们不能创建 Policy例如,这就是为什么为 Policy 创建扩展方法没有意义的原因。类(class)。


  • 这是克服这些限制的一种方法:
    public static class PolicyExt
    {
    public static PolicyBuilder HandleExcept<TException>() where TException : Exception
    => Policy.Handle((Exception exception) => exception is TException is false);

    public static PolicyBuilder HandleExcept<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception
    => Policy.Handle((Exception exception) => exception is TException is false || exception is TException texception && !exceptionPredicate(texception));
    }

    public static class PolicyExt<TResult>
    {
    public static PolicyBuilder<TResult> Handle<TException>() where TException : Exception
    => Policy<TResult>.Handle((Exception exception) => exception is TException is false);

    public static PolicyBuilder<TResult> Handle<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception
    => Policy<TResult>.Handle((Exception exception) => exception is TException is false || exception is TException texception && !exceptionPredicate(texception));
    }
    最后是一个快速测试:
    var policy = PolicyExt.HandleExcept<Exception>(ex => ex is NotSupportedException)
    .WaitAndRetry(2, _ => TimeSpan.FromSeconds(2));

    //Or just:
    //var policy = PolicyExt.HandleExcept<NotSupportedException>()
    // .WaitAndRetry(2, _ => TimeSpan.FromSeconds(2));

    policy.Execute(() =>
    {
    Console.WriteLine("Have been called");
    throw new NotSupportedException();
    });
    输出:
    Have been called
    Unhandled exception. System.NotSupportedException: Specified method is not supported.
  • 所以,万一NotSupportedException重试逻辑未触发。
  • 但是如果我们针对以下委托(delegate)执行策略:

  • policy.Execute(() =>
    {
    Console.WriteLine("Have been called");
    throw new Exception("Custom");
    });
    然后输出将如下:
    Have been called
    Have been called
    Have been called
    Unhandled exception. System.Exception: Custom
    因此,触发了重试。

    关于c# - Polly 重试除特定条件外的所有异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50948654/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com