合并的可观察序列不会在出错时重试

时间:2016-01-21 13:12:10

标签: c# .net exception-handling system.reactive

信息:

该方法的目的是从流中获取秘密,从流中获取uri。然后使用秘密和一些其他参数typename点击uri以获取一些数据。

Secrets.GetSecret()IObservable<string>Urls.GetHostUrl()IObservable<Uri>

问题

我遇到的问题是,如果dataFetcher.GetFromUrl调用抛出异常,则observable终止。 RetryAfterDelay扩展方法似乎根本不起作用。

我希望能够捕获并记录异常,但理想情况下不能使用observable终止。或者如果它必须终止然后重新订阅原始流,那么它的行为就好像它已经记录/吞下了异常。

原因是网络/主机不是最稳定的,因此有时它可能会出错。

方式

private IObservable<string> GetFromHostUrl(string type, string name, int retryTime)
{
    return Observable.Interval(TimeSpan.FromSeconds(retryTime), schedulerProvider.Default).StartWith(-1L)
        .CombineLatest(Observable.Defer(() => Secrets.GetSecret()),
                                              Urls.GetHostUrl(),
                                              (_, secret, hostUrl) => dataFetcher.GetFromUrl(hostUrl, type, name, secret).Result)
        .Do(s =>
                {
                    // log success
                },
                e =>
                {
                    // log failure
                })
        .DistinctUntilChanged()
        .RetryAfterDelay(TimeSpan.FromSeconds(retryTime), schedulerProvider.Default)
        .Replay(1)
        .RefCount();
}

扩展方法

// c/o: http://stackoverflow.com/questions/18978523/write-an-rx-retryafter-extension-method
public static class ExtensionMethods
{

    private static IEnumerable<IObservable<TSource>> RepeateInfinite<TSource>(IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
    {
        // Don't delay the first time        
        yield return source;

        while (true)
        {
            yield return source.DelaySubscription(dueTime, scheduler);
        }
    }

    public static IObservable<TSource> RetryAfterDelay<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
    {
        return RepeateInfinite(source, dueTime, scheduler).Catch();
    }
}

1 个答案:

答案 0 :(得分:0)

听起来像是Retry的教科书示例。

public static IObservable<TSource> RetryAfterDelay<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
{
    return RepeateInfinite(source, dueTime, scheduler).Retry();
}