Reactive:将合并的IObservable转换为一个与BehaviorSubject类似的流

时间:2011-03-09 18:22:48

标签: c# .net system.reactive

以下是我的示例代码......

var rootSubject = new Subject<Types>();

var firstSubject = rootSubject.Where(x => x == Types.First);
var secondSubject = rootSubject.Where(x => x == Types.Second);
var thirdSubject = rootSubject.Where(x => x == Types.Third);
var forthSubject = rootSubject.Where(x => x == Types.Forth);

var mergedSubject = Observable.Merge(firstSubject, secondSubject, thirdSubject, forthSubject)
                        .Timeout(TimeSpan.FromSeconds(2), Observable.Return(Types.Error))
                        .Replay()
                        .RefCount();

rootSubject.OnNext(Types.Second);

var result = mergedSubject.First();

Console.WriteLine(String.Format("result - {0}", result));

由于某种原因,它总是超时并返回错误类型。有什么想法在这里发生吗?

我想要做的是创建一个合并的Iobservable,它是一个像BehaviorSubject一样的流,所以如果在.First()之前调用.OnNext(...),首先会有一个值。

2 个答案:

答案 0 :(得分:3)

我认为问题在于你基本上没有连接重播序列 - 或者可能太晚了。 (我不知道RefCount的详细信息,但我怀疑只有当订阅它时它才会连接。)

这是一个有效的替代方案:

var mergedSubject = Observable
    .Merge(firstSubject, secondSubject, thirdSubject, forthSubject)
    .Timeout(TimeSpan.FromSeconds(2), Observable.Return(Types.Error))
    .Replay();

mergedSubject.Connect();
rootSubject.OnNext(Types.Second);

var result = mergedSubject.First();

我不知道这是否满足您所需的一切,但它至少会为您的测试代码打印出正确的结果:)

答案 1 :(得分:0)

Jon怀疑RefCount只有在订阅了某个东西时才会连接,这是正确的。所以,如果你真的需要RefCount,你也可以这样做:

var rootSubject = new Subject<Types>();
var firstSubject = rootSubject.Where(x => x == Types.First);
var secondSubject = rootSubject.Where(x => x == Types.Second);
var thirdSubject = rootSubject.Where(x => x == Types.Third);
var forthSubject = rootSubject.Where(x => x == Types.Fourth);
var mergedSubject = 
    Observable.Merge(firstSubject, secondSubject, thirdSubject, forthSubject)  
    .Timeout(TimeSpan.FromSeconds(2), Observable.Return(Types.Error))
    .Replay().RefCount();

//added
mergedSubject.Subscribe();  

rootSubject.OnNext(Types.Second);

var result = mergedSubject.First();

Console.WriteLine(String.Format("result - {0}", result));