Polly 中是否有一种方法可以重试除指定的异常之外的所有异常.. 例如:
var p = Policy
.Handle<HttpListenerException>(e => !(e.NativeErrorCode == 1))
.Or<Exception>()
.RetryAsync();
Run Code Online (Sandbox Code Playgroud)
在这里,我选择了一个略显做作的情况,我会想不是在重试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;
}
Run Code Online (Sandbox Code Playgroud)
那是线程安全的吗?:|
如果您查看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);
...
}
Run Code Online (Sandbox Code Playgroud)
PolicyBuilder,该类具有内部 ctor。
Policy没有公共 ctor。
Policy,这就是为什么为类创建扩展方法没有意义Policy。这是克服这些限制的一种方法:
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));
}
Run Code Online (Sandbox Code Playgroud)
最后这是一个快速测试:
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();
});
Run Code Online (Sandbox Code Playgroud)
输出:
Have been called
Unhandled exception. System.NotSupportedException: Specified method is not supported.
Run Code Online (Sandbox Code Playgroud)
NotSupportedException重试逻辑没有被触发。Have been called
Unhandled exception. System.NotSupportedException: Specified method is not supported.
Run Code Online (Sandbox Code Playgroud)
然后输出将如下:
Have been called
Have been called
Have been called
Unhandled exception. System.Exception: Custom
Run Code Online (Sandbox Code Playgroud)
因此,重试被触发。
| 归档时间: |
|
| 查看次数: |
2174 次 |
| 最近记录: |