如何在捕获错误后选择observable的下一项?

时间:2016-11-02 10:56:26

标签: .net system.reactive

我正在从TCP端点读取数据流。这可能是错误,或者是下降,此时我想尝试连接到辅助端点。

我想使用Observable.Repeat创建一个无限的端点列表,然后选择其中一个来创建一个流。如果出错,我想切换到下一个。我怎么能这样做呢?

2 个答案:

答案 0 :(得分:1)

麻烦在于在重新订阅时保持使用哪个源的状态。可能有比使用IEnumerator更好的选择,但它可能没有使用Retry语义。

            //sample source which throws an error after 5 entries
            Func<string, IObservable<string>> sampleSource =
                endpoint =>
                Observable
                .Interval(TimeSpan.FromSeconds(0.5))
                .Select(i => $"{endpoint} : {i + 1}")
                .Take(5)
                .Concat(Observable.Throw<string>(new Exception()));

            //infinite sequence of sources
            var endpoints = new string[] { "source1", "source2" }.Repeat();

            var sequence =
            Observable.Using
            (
                endpoints.GetEnumerator,
                enumerator => Observable.Create<string>(observer =>
                {
                    enumerator.MoveNext();
                    observer.OnNext(enumerator.Current);
                    return Disposable.Empty;
                })
                .SelectMany(sampleSource)
                .Retry()
           );

            sequence.Subscribe(c => Console.WriteLine(c));

            Console.ReadLine();

输出:

source1 : 1
source1 : 2
source1 : 3
source1 : 4
source1 : 5
source2 : 1
source2 : 2
source2 : 3
source2 : 4
source2 : 5
source1 : 1
source1 : 2

答案 1 :(得分:0)

一些示例代码会有所帮助,因此回答者不必编写内容并将其添加到糟糕的电影参考中......

void Main()
{
    var initialObservable = new Subject<int>();
    var observableToContinueWithAfterError = Observable.Return(10);
    var chainedObservable = initialObservable.Catch(observableToContinueWithAfterError);

    chainedObservable.Subscribe(
        i => Console.WriteLine(i), 
        e => Console.WriteLine("Too bad AC ain't in charge no more (this won't happen, Observable.Catch swallows the exception)."),
        () => Console.WriteLine("Keep the change you..."));
    initialObservable.OnNext(1);
    initialObservable.OnNext(2);
    initialObservable.OnError(new Exception());
}

有关Observable.Catch的详细信息,请参阅here