我正在尝试扩展我对 Rx 的了解。所以我只是在玩流,并试图让它们表现得像我期望的那样。
虽然我已经阅读过,Repeat() 运算符在实践中存在困难,因为您可能会在 OnCompleted 和重新订阅之间丢失通知,但我自己无法弄清楚为什么会发生以下情况。
var subject = new Subject<string>();
var my = subject
.Take(1)
.Merge(Observable.Empty<string>().Delay(TimeSpan.FromMilliseconds(2000)))
.Repeat();
my.Subscribe(Console.WriteLine);
var stopwatch = new Stopwatch();
stopwatch.Start();
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(1), () => subject.OnNext("1 at " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(2), () => subject.OnNext("2 at " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(3), () => subject.OnNext("3 at " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(4), () => subject.OnNext("4 at " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(5), () => subject.OnNext("5 at " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(6), () => subject.OnNext("6 at " + stopwatch.ElapsedMilliseconds));
Console.ReadLine();
当我运行这个例子时,结果是完全不确定的:
结果1:
1 at 1006
3 at 3007
5 at 4995
很好的是它忽略了 2 和 4,但即使在这个结果内部也有一些奇怪,因为实际上 3 和 5 之间并没有真正的 2 秒差距。
然而,结果可能更糟。看到这个:
1 at 1003
2 at 2003
4 at 4005
6 at 6004
1 和 2 之间没有 2 秒的间隔。正好是 1 秒。他为什么不把它放在一边?
如果有人能为我澄清事情,我会非常高兴!
编辑
我只是注意到这里可能是错误的合并。如果我将查询重构为 Concat 事情似乎应该发生:
var my = subject
.Take(1)
.Concat(Observable.Empty<string>().Delay(TimeSpan.FromMilliseconds(2000)))
.Repeat();