我已经包装了瞬态故障处理应用程序块的重试类别的executeasync方法如下:
public class RetryWrapper
{
public Task IncrementalAsync(Func<Task> action)
{
var retryStrategy = new Incremental(3, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
var retryPolicy = new RetryPolicy<AzureServiceBusDetectionStrategy>(retryStrategy);
retryPolicy.Retrying += (sender, args) =>
{
Console.WriteLine("Retry - Count = {0}, Delay = {1}, Exception = {2}",
args.CurrentRetryCount, args.Delay, args.LastException.Message);
};
return retryPolicy.ExecuteAsync(action);
}
}
从我的客户端功能中,我像以下内容一样调用它:
RetryWrapper retry = new RetryWrapper();
try
{
retry.IncrementalAsync<bool>(this.SomeFunction);
}
catch (Exception ex)
{
Console.WriteLine("All retries failed. Exception details: {0}", ex.ToString());
}
和某些功能定义是:
public async Task<bool> SomeFunction()
{
await Task.Delay(100);
throw new Exception("Incremental execute task generic");
}
当我运行程序时,它会重试3次,但在最后一次尝试中,并未引发异常,因为它使用执行方法发生:
Retry - Count = 1, Delay = 00:00:01, Exception = Incremental execute task generic
Retry - Count = 2, Delay = 00:00:03, Exception = Incremental execute task generic
Retry - Count = 3, Delay = 00:00:05, Exception = Incremental execute task generic
从executeaync方法进行所有重试后,如何捕获异常?另外,使用像这样的包装班好吗?目的是将瞬态块代码集中到一个地方,因此明天我可以切换库。请建议是否有更好的模式。
由于例外是重试事件处理程序的事件参数的一部分,所以我猜想重试策略本身正在捕获例外。您可能无法在尝试捕获中直接获得异常,因为该策略的内部工作并未使异常。
但是,您可以在RetryWrapper
类中添加一些支持属性。
public class RetryWrapper
{
private const Int32 RetryTimes = 3;
// Can be private if you don't need all available to caller.
public IList<Exception> Exceptions { get; private set; }
public Exception LastException => Exceptions.LastOrDefault() ?? null;
public Boolean Failed => Exceptions.Count == _retryTimes;
public RetryWrapper() {
Exceptions = new List<Exception>();
}
public Task IncrementalAsync(Func<Task> action)
{
var retryStrategy = new Incremental(RetryTimes, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
var retryPolicy = new RetryPolicy<AzureServiceBusDetectionStrategy>(retryStrategy);
retryPolicy.Retrying += (sender, args) =>
{
Console.WriteLine("Retry - Count = {0}, Delay = {1}, Exception = {2}",
args.CurrentRetryCount, args.Delay, args.LastException.Message);
Exceptions.Add(args.LastException);
};
return retryPolicy.ExecuteAsync(action);
}
}
然后
RetryWrapper retry = new RetryWrapper();
retry.IncrementalAsync<bool>(this.SomeFunction);
if (retry.Failed)
{
Console.WriteLine("All retries failed. Exception details: {0}", retry.LastException.Message.ToString());
}