Je cherche à approfondir mes connaissances sur Rx. Je m'amuse donc à manipuler des flux et à essayer de les faire se comporter comme je m'y attendrais.
Alors que j'ai lu précédemment que l'opérateur Repeat() posait des difficultés en pratique car vous pourriez perdre des notifications entre OnCompleted et la nouvelle souscription, je ne parviens pas à comprendre pourquoi cela se produit.
var subject = new Subject();
var my = subject
.Take(1)
.Merge(Observable.Empty().Delay(TimeSpan.FromMilliseconds(2000)))
.Repeat();
my.Subscribe(Console.WriteLine);
var stopwatch = new Stopwatch();
stopwatch.Start();
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(1), () => subject.OnNext("1 à " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(2), () => subject.OnNext("2 à " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(3), () => subject.OnNext("3 à " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(4), () => subject.OnNext("4 à " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(5), () => subject.OnNext("5 à " + stopwatch.ElapsedMilliseconds));
Scheduler.ThreadPool.Schedule(TimeSpan.FromSeconds(6), () => subject.OnNext("6 à " + stopwatch.ElapsedMilliseconds));
Console.ReadLine();
Lorsque j'exécute cet exemple, les résultats sont totalement non déterministes :
Résultat 1 :
1 à 1006
3 à 3007
5 à 4995
C'est bien qu'il ait omis le 2 et le 4 mais même à l'intérieur de ce résultat, il y a quelque chose d'étrange car en réalité il n'y a pas un écart de 2 secondes entre le 3 et le 5.
Cependant, les résultats peuvent être encore pires. Voyez celui-ci :
1 à 1003
2 à 2003
4 à 4005
6 à 6004
Il n'y a pas d'écart de 2 secondes entre 1 et 2. C'est exactement une seconde. Pourquoi ne l'a-t-il pas exclu ?
Si quelqu'un pouvait éclaircir les choses pour moi, je serais plus que ravi !
ÉDITER
Je viens de remarquer que c'est peut-être le Merge qui pose problème ici. Si je remanie ma requête pour utiliser Concat, les choses semblent se passer comme elles devraient :
var my = subject
.Take(1)
.Concat(Observable.Empty().Delay(TimeSpan.FromMilliseconds(2000)))
.Repeat();