Я пытаюсь расширить свои знания по 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 секунды нет. Это ровно одна секунда.Почему он не оставил это?
Если бы кто-то мог прояснить для меня вещи, я был бы более чем счастлив!
РЕДАКТИРОВАТЬ
Iпросто заметил, что это может быть Слияние, которое здесь не так.Если я проведу рефакторинг моего запроса в Concat, то все произойдет так, как должно:
var my = subject
.Take(1)
.Concat(Observable.Empty<string>().Delay(TimeSpan.FromMilliseconds(2000)))
.Repeat();