所以我希望我的标题足够准确,但是我现在非常处于“看不见树木的状态”。
一段时间以来,我一直在研究C#的反应式扩展,直到现在它的表现直观而奇妙,然后我遇到了一个问题:
我创建了一个主题
我创建一个值Observable.Create并调用Subscribe
该值然后愉快地弹出我的OnNext()
lambda,万岁!
但是,如果我创建后续的Observable.Return和订阅...,则不会发生任何事情,并且主题包含HasObservers: false
我整理了一个演示该问题的最小控制台片段
using System.Reactive.Linq;
using System.Reactive.Subjects;
static void Main(string[] args)
{
Subject<string> messenger = new Subject<string>();
messenger.Where(o => o.Length > 0).Subscribe(file => { Console.WriteLine("got file request: " + file); });
var pathObservable = Observable.Return<string>("File 1");
pathObservable.Subscribe(messenger);
var pathObservable2 = Observable.Return<string>("File 2");
pathObservable2.Subscribe(messenger);
Console.ReadKey();
}
结果:
注意:在有人问我为什么要像使用两个可观察对象(一个序列可以完成)那样愚蠢地做某事之前,这只是一个例子;实际上,两个单独的可观察的创建调用是独立的,并且受到外部文件请求的启发,在这种情况下,问题在于第一个请求成功,而第二个请求成功。
我尝试使用Observable.Create()代替,并使用单个值调用OnNext,结果相同;有趣的是,在这种情况下,在lambda中有一个断点表明,OnNext正在被调用以用于第二个可观察到的事件,只是没有弹出到主题中
任何有关我错过或误解的想法都非常受欢迎, 预先感谢
答案 0 :(得分:2)
最简单的方法是按照Paulo的建议仅订阅OnNext
消息。您还可以从可观察对象中删除或隐藏OnCompleted
条消息。
但是,最好的方法是替换messenger
主题。我不知道您的用例较大,但是一个很好的目标是尽量减少使用Subject。它们非常适合学习,对于应用程序来说很糟糕。
在这种情况下,您可以用单行代码替换整个代码:
Observable.Merge(
Observable.Return<string>("File 1"),
Observable.Return<string>("File 2")
)
.Where(o => o.Length > 0)
.Subscribe(file => Console.WriteLine("got file request: " + file));
如果要模拟动态添加可观察对象,则可能需要使用Subject<IObservable<string>>
:
Subject<IObservable<string>> consoleWriter = new Subject<IObservable<string>>();
consoleWriter
.Merge()
.Where(o => o.Length > 0)
.Subscribe(file => Console.WriteLine("got file request: " + file));
var pathObservable = Observable.Return<string>("File 1");
consoleWriter.OnNext(pathObservable);
var pathObservable2 = Observable.Return<string>("File 2");
consoleWriter.OnNext(pathObservable2);
答案 1 :(得分:0)
通过让messenger
订阅另一个可观察对象,您将使它订阅OnNext
,OnError
和OnCompleted
。
如果您在创建Subject<string>
之后添加此代码,则会发现它已完成:
messenger.Subscribe(_ => {}, e => Console.WriteLine(e), () => Console.WriteLine("Completed"));
相反,如果您仅添加一个后续操作,则该主题将不会完成:
Subject<string> messenger = new Subject<string>();
messenger.Where(o => o.Length > 0).Subscribe(file => { Console.WriteLine("got file request: " + file); });
var pathObservable = Observable.Return<string>("File 1");
pathObservable.Subscribe(v => messenger.OnNext(v));
var pathObservable2 = Observable.Return<string>("File 2");
pathObservable2.Subscribe(v => messenger.OnNext(v));
messenger.OnNext("File 3");
Console.ReadLine();
输出:
got file request: File 1
got file request: File 2
got file request: File 3