使用Hot Observables时,Observable.Retry()无法正常工作

时间:2018-05-09 20:15:08

标签: c# system.reactive

我有以下可观察序列

int num = 0;            

var o = Observable.Create<int>(observer => Task.Run(() =>
{
    var rnd = new Random((int)DateTime.Now.Ticks);
    Console.WriteLine($"Starting subscription loop # {++num}");
    for (int i=0;i<100;i++)
    {
        Thread.Sleep(200);

        if (i == 3)
        {
            observer.OnError(new ApplicationException("test exception"));
            break;
        }

        observer.OnNext(rnd.Next(0, 50));
    }
})).Publish().RefCount();

以及以下通知处理程序

o
    .Retry()
    .Subscribe(Console.WriteLine, ex => Console.WriteLine($"Exception occurred: {ex.Message}"), () => Console.WriteLine("Completed"));

这是我的输出

Starting subscription loop # 1
47
27
12
Starting subscription loop # 2
Starting subscription loop # 3
Starting subscription loop # 4
Starting subscription loop # 5
Starting subscription loop # 6
Starting subscription loop # 7
Starting subscription loop # 8
Starting subscription loop # 9
...

我在Lee Campbell's IntroToRx本书

中阅读了以下内容
  

如果您希望序列遇到可预测的问题,   你可能只是想重试一下。你想要的一个这样的例子   重试是在执行I / O(例如Web请求或磁盘访问)时。 I / O   因间歇性故障而臭名昭着。重试扩展方法   提供在指定次数或失败时重试失败的能力   直到成功。

我在示例中注意到的行为与Campbell记录的行为不符,也不符合他的样本。我错过了什么?

如果我不Publish().RefCount(),那就可以了。

1 个答案:

答案 0 :(得分:1)

当一个可观察到的错误出现时,它已经死了并且已经完成了。不再有通知流出。在您的情况下,o错误,由于.Publish().Refcount()Retry正在尝试重新订阅相同的可观察对象(已死亡并已完成)。这就是Publish的作用:它不是创建新的可观察对象,而是将多个客户端订阅到相同的可观察对象。

如果您移除.Publish().Refcount(),您将看到它尝试重新订阅新的观察结果。