使用System.Reactive
时遇到了一些奇怪的事情。也许这是正常的行为,但对我来说意义不大。
让我们采用以下代码:
Subject<IObservable<long>> X = new Subject<IObservable<long>>();
IObservable<long> I = Observable.Interval(TimeSpan.FromSeconds(1));
async Task Main()
{
X.Switch().Subscribe(x => Console.WriteLine($"switched_1: {x}"));
I.Subscribe(x => Console.WriteLine($"direct_1: {x}"));
X.Switch().Subscribe(x => Console.WriteLine($"switched_2: {x}"));
I.Subscribe(x => Console.WriteLine($"direct_2: {x}"));
await Task.Factory.StartNew(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false);
X.Switch().Subscribe(x => Console.WriteLine($"switched_3 !!!: {x}"));
I.Subscribe(x => Console.WriteLine($"direct_3: {x}"));
});
X.OnNext(Observable.Interval(TimeSpan.FromSeconds(1)));
Console.ReadLine();
X.OnNext(Observable.Interval(TimeSpan.FromSeconds(1)));
Console.WriteLine("New observable emited");
Console.ReadLine();
}
可观察到的标有!!!直到发出第二个间隔才被击中。
[更新]
我想我知道发生了什么:每次订购新开关时,我都在订阅上游的观察值。而且,在执行此操作时,我只会收到有关订阅后发出的可观察对象的通知,而我无法“连接”到当前可观察对象。 我以为只使用一次 switch ,以后订阅可观察的结果将有所帮助:
Subject<IObservable<long>> X = new Subject<IObservable<long>>();
IObservable<long> XI;
void Main()
{
XI = X.Switch().AsObservable();
XI.Subscribe(x => Console.WriteLine($"switched_1: {x}"));
XI.Subscribe(x => Console.WriteLine($"switched_2: {x}"));
X.OnNext(Observable.Interval(TimeSpan.FromSeconds(1)));
XI.Subscribe(x => Console.WriteLine($"switched_3 !!!: {x}"));
Console.ReadLine();
X.OnNext(Observable.Interval(TimeSpan.FromSeconds(1)));
Console.WriteLine("New observable emited");
Console.ReadLine();
}
但不是:(
[更新2]
似乎我找到了一个切实可行的解决方案,但是我不确定该解决方案是否正确使用。
Subject<IObservable<long>> X = new Subject<IObservable<long>>();
IObservable<long> XI;
async Task Main()
{
XI = X.Switch().Publish().AutoConnect();
...
如何从一开始就使它起作用?
答案 0 :(得分:1)
您在[更新]下的解释是正确的,因为 Task.Factory.StartNew 返回的是Task
但是,仅像[Update2]中那样公开XI-Observable,并隐藏下面有切换的事实是可行的选择。
使用Publish()。AutoConnect()可以将可观察对象从冷转换为热。您还可以在代码段上尝试使用BehaviorSubject或ReplaySubject来了解冷热之间的区别。如果您了解这些差异,那么对您来说应该更加清楚,您实际想到的解决方案应该是什么样子。