【发布时间】:2012-06-08 06:38:15
【问题描述】:
原始问题
我有一个场景,我有多个 IObservable 序列,我想将它们与 Merge 组合然后收听。但是,如果其中一个产生错误,我不希望它使其他流的所有内容崩溃,也不想重新订阅序列(这是一个“永久”序列)。
我通过在合并之前将Retry() 附加到流中来做到这一点,即:
IEnumerable<IObservable<int>> observables = GetObservables();
observables
.Select(o => o.Retry())
.Merge()
.Subscribe(/* Do subscription stuff */);
但是,当我想对此进行测试时,问题就出现了。我想测试的是,如果observables 中的IObservable 之一产生OnError,其他的应该仍然能够发送它们的值并且它们应该得到处理
我以为我会在observables 中使用两个Subject<int>s 代表两个IObservables;一个发送OnError(new Exception()),另一个发送OnNext(1)。但是,Subject<int> 似乎会为新订阅重放所有以前的值(实际上是Retry()),从而将测试变成无限循环。
我试图通过创建手册IObservable 来解决它,该手册在第一次订阅时会产生错误,然后是空序列,但感觉很hacky:
var i = 0;
var nErrors = 2;
var testErrorObservableWithOneErrorAndThenCompletion = Observable.Create<int>(o => {
i++;
if (i < nErrors) {
return Observable.Throw<int>(new Exception()).Subscribe(o);
} else {
return Observable.Empty<int>().Subscribe(o);
}
});
我是否以错误的方式使用Subject 或考虑Retry()?对此还有其他想法吗?您将如何解决这种情况?
更新
好的,这是我想要的和 想 Retry() 的大理石图。
o = message, X = error.
------o---o---X
\
Retry() -> \---o---o---X
\
Retry() -> \...
我的问题可能更多是因为我没有一个好的股票类来使用前测试,因为Subject 想要重放我以前的所有错误。
更新 2
这是一个测试用例,显示了我对 Subject 重放其值的意思。如果我说它以 cold 的方式这样做,我是否正确使用了该术语?我知道Subject 是一种创建热可观察对象的方式,但这种行为对我来说仍然感觉“冷”。
var onNext = false;
var subject = new Subject<int>();
subject.Retry().Subscribe(x => onNext = true);
subject.OnError(new Exception());
subject.OnNext(1);
Assert.That(onNext, Is.True);
【问题讨论】:
标签: c# .net system.reactive subject