Rxに関する知識を広げようとしています。ですから、私はストリームをいじって、期待どおりに動作させるようにしています。
OnCompletedと再サブスクリプションの間の通知が失われる可能性があるため、Repeat()演算子は実際には困難であると読んだことがありますが、次のことがなぜ発生するのかを自分で理解することはできません。
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();