我一直在考虑为一个简单的网络流实现一个基本的重试逻辑。其想法是有三种类型的例外需要处理:
当我勾勒这幅画的时候,我的结果是
var retriedObservable = observable.RetryWhen(x => x.SelectMany(ex =>
{
if (ex is ShouldCompleteException)
{
return Observable.Return<Exception>(null);
}
else if (ex is TransientNetworkException)
{
return Observable.Return(ex).Delay(TimeSpan.FromSeconds(1));
}
else
{
return Observable.Throw<Exception>(ex);
}
}).TakeUntil(ex => ex == null));编辑:这个例子非常简单,只显示了我在代码中看到的三种典型的错误处理模式。在现实世界中,当然还有更多。
该代码工作正常,但看起来过于复杂,我不确定特殊的'null‘值是否会在某个时候击中我的脸。
我还尝试了.Where()和.Merge()的组合,但是代码很快就变得不可读了。
是否有更清晰的方法(即更规范的方法)来完成这一基本错误处理?
发布于 2018-09-26 18:40:36
这有一点帮助:
var retriedObservable2 = observable.RetryWhen(exStream => Observable.Merge(
exStream.OfType<ShouldCompleteException>().Select(_ => (Exception)null),
exStream.NotOfType(typeof(ShouldCompleteException)).OfType<TransientNetworkException>().Delay(TimeSpan.FromSeconds(1)),
exStream.NotOfTypes(typeof(ShouldCompleteException), typeof(TransientNetworkException)).SelectMany(e => Observable.Throw<Exception>(e))
).TakeUntil(ex => ex == null));它使用以下扩展消息:
public static class X
{
public static IObservable<TSource> NotOfType<TSource>(this IObservable<TSource> source, Type t)
{
return source.Where(o => !t.IsInstanceOfType(o));
}
public static IObservable<TSource> NotOfTypes<TSource>(this IObservable<TSource> source, params Type[] ts)
{
return source.Where(o => ts.All(t => !t.IsInstanceOfType(o)));
}
}发布于 2018-09-24 10:00:16
这里已经有了很好的库,比如波莉。但是,如果你想实现你自己的,你可以做如下的事情。
您可以创建一个RetryPolicyHandler类。此外,您还可以使用接口对其进行抽象,如果需要,可以与任何IoC容器一起使用。使用以下实现添加类似于RetryExecuteAsync的方法。
public async Task RetryExecuteAsync(Func<Task> action)
{
int retryCount = default(int);
int maxNumberOfRetries = 5; // Or get from settings
while (true)
{
try
{
await action().ConfigureAwait(false);
break;
}
catch (ArgumentNullException)
{
// Something specific about this exception
if (++retryCount > maxNumberOfRetries)
throw;
}
catch (Exception)
{
if (++retryCount > maxNumberOfRetries)
throw;
}
}
}然后你就可以这样用它了。
await this.retryPolicyHandler.RetryExecuteAsync(async () =>
{
// Whatever code you want to retry
}).ConfigureAwait(false);如果需要,还可以创建其他特定方法。例如,ExecuteDeadlockRetryAsync可以捕获SqlException或ExecuteHttpCallRetryAsync来处理HttpRequestException,并以另一种方式处理它们。
https://stackoverflow.com/questions/52476429
复制相似问题