如何处理executeasync方法中的异常



我已经包装了瞬态故障处理应用程序块的重试类别的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());
}

最新更新