如果您查看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
具有内部 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));
}
最后是一个快速测试:
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
重试逻辑没有被触发。
- 但是,如果我们针对以下委托执行策略:
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
因此,触发了重试。