我试图使用C#observables编写重试机制。
这是我尝试做的事情:
public static IObservable<T> Retry(GenericRetryExecutorRequest<T> request)
{
var source = Observable.Timer(TimeSpan.Zero, request.Interval)
.Select(item =>
{
return request.GenericRetryActions.OnExecute();
});
var retryObservable = source
.Retry(request.RetryCount)
.Catch(source);
return retryObservable;
}
public class GenericRetryExecutorRequest<T>
{
public int RetryCount { get; set; } = 3;
public TimeSpan Interval { get; set; } = new TimeSpan(0,0,0,5);
public IGenericRetryActions<T> GenericRetryActions { get; set; }
}
public interface IGenericRetryActions<out T>
{
T OnExecute();
void OnCatch();
}
不幸的是 - 它表现不佳:
OnCatch
。
我尝试了许多方法但没有成功。OnExecute
似乎没有重复执行(请求
如果它抛出异常,则为答案 0 :(得分:1)
试试这个:
public void setMessageToSend(Message message) {
messagesToSend.add(message.getMessageHandler().getBytes());
messagesToSend.notify();
}
通常在观察者中使用try-catch是不受欢迎的;最好使用可观察的On-Error异常处理。但是,您的界面public static IObservable<T> Retry<T>(this GenericRetryExecutorRequest<T> request)
{
return Observable.Timer(Timespan.Zero, request.Interval)
.Select(item =>
{
try
{
var value = request.GenericRetryActions.OnExecute();
return Notification.CreateOnNext(value);
}
catch(Exception e)
{
request.GenericRetryActions.OnCatch();
return Notification.CreateOnError<T>(e);
}
})
.Dematerialize()
.Retry(request.RetryCount);
}
不会返回OnExecute
,而只会返回IObservable<T>
。所以你被迫使用try-catch。如果您要更改界面以返回T
,那么我认为这样可行:
IObservable<T>
这就是假设您希望机制继续成功。如果没有,请在任一解决方案的末尾添加public class GenericRetryExecutorRequest2<T>
{
public int RetryCount { get; set; } = 3;
public TimeSpan Interval { get; set; } = new TimeSpan(0, 0, 0, 5);
public IGenericRetryActions2<T> GenericRetryActions { get; set; }
}
public interface IGenericRetryActions2<out T>
{
IObservable<T> OnExecute();
void OnCatch();
}
public static IObservable<T> Retry2<T>(this GenericRetryExecutorRequest2<T> request)
{
return Observable.Timer(Timespan.Zero, request.Interval)
.SelectMany(_ => request.GenericRetryActions.OnExecute())
.Catch((Exception e) => Observable.Return(Unit.Default)
.Do(_ => request.GenericRetryActions.OnCatch())
.SelectMany(Observable.Throw<T>(e))
)
.Retry(request.RetryCount);
}
。