2016-03-24 20 views
0

Birisi Gözlemlenebilir.Join'i iki farklı gözlenebilir tiple nasıl kullanacağınıza dair bir örnek verebilir misiniz?
found so far here adresindeki en iyi açıklama, soldaki pencerenin açılabileceğini, sağdaki pencerenin bu pencerede bir eşleşme bulmak için olduğunu belirtti. Peki bu leftDurationSelector ve rightDurationSelector nasıl çalışıyor? Örnek, sadece ne yaptığını anlamadığım Publish().RefCount() kullanıyor. Benim için bir süre seçici, bir zaman dilimi gibi, örn. Bir Tampon penceresi.Gözlemlenebilir.Join örneği

cevap

2

İşte neyin güzel olduğunu gösteren bir örnek. iki zaman damgalı gözlenebilirler her 0 ile 10.0 saniyelik bir rastgele aralıklarla bir değer üretmek & sourceBsourceA üreterek

Let başlangıç:

Random rnd = new Random(); 
IObservable<int> source = 
    Observable 
     .Generate(0, x => true, x => x + 1, x => x, 
      x => TimeSpan.FromSeconds(rnd.NextDouble()* 10.0)); 

IObservable<Timestamped<string>> sourceA = source.Select(x => $"A{x}").Timestamp(); 
IObservable<Timestamped<string>> sourceB = source.Select(x => $"B{x}").Timestamp(); 

çıkış değerleri için güzel bir şekilde yapalım:

Örneğin,Örneğin, "A1 @ 12:33:09.2" numaralı telefonu döndürebilir. Şimdi

katılmak: Ben değeri ya sourceA & sourceB kadar eşleştirilmiş sonuçları olduğunu olsun

 
A1 @ 12:33:09.2, B0 @ 12:33:12.4 
A3 @ 12:33:23.8, B1 @ 12:33:20.9 
A3 @ 12:33:23.8, B2 @ 12:33:25.6 
A3 @ 12:33:23.8, B3 @ 12:33:25.9 
A4 @ 12:33:30.6, B4 @ 12:33:33.0 
A5 @ 12:33:37.9, B5 @ 12:33:35.7 
A5 @ 12:33:37.9, B6 @ 12:33:40.3 
A5 @ 12:33:37.9, B7 @ 12:33:40.8 
A6 @ 12:33:43.3, B6 @ 12:33:40.3 
A6 @ 12:33:43.3, B7 @ 12:33:40.8 
A7 @ 12:33:44.5, B7 @ 12:33:40.8 
A7 @ 12:33:44.5, B8 @ 12:33:44.9 
A6 @ 12:33:43.3, B8 @ 12:33:44.9 

:

IObservable<string> query = 
    sourceA.Join(sourceB, 
     a => Observable.Timer(TimeSpan.FromSeconds(4.0)), 
     b => Observable.Timer(TimeSpan.FromSeconds(4.0)), 
     (at, bt) => $"{format(at)}, {format(bt)}"); 

ben bu sorgu abone olursanız böyle bir sonuç elde diğerinin 4.0 saniye içinde üretilmiştir.

Şimdi sourceA değerinden 4.0 saniye sonra üretildiği sürece sadece sourceB'dan bir değer isteseydim, ama başka yoldan değil miydi?

IObservable<string> query = 
    sourceA.Join(sourceB, 
     a => Observable.Timer(TimeSpan.FromSeconds(4.0)), 
     b => Observable.Timer(TimeSpan.FromSeconds(0.0)), 
     (at, bt) => $"{format(at)}, {format(bt)}"); 

me verir: "B" nin tüm s 'ler "A" sonra ortaya'

 
A0 @ 12:41:35.4, B1 @ 12:41:35.5 
A1 @ 12:41:42.7, B2 @ 12:41:43.2 
A3 @ 12:41:47.6, B3 @ 12:41:51.0 
A4 @ 12:41:49.8, B3 @ 12:41:51.0 
A7 @ 12:42:00.2, B4 @ 12:42:00.4 
A7 @ 12:42:00.2, B5 @ 12:42:02.5 
A7 @ 12:42:00.2, B6 @ 12:42:03.5 
A8 @ 12:42:04.8, B7 @ 12:42:06.4 
A9 @ 12:42:12.3, B8 @ 12:42:15.2 
A10 @ 12:42:17.2, B9 @ 12:42:19.7 
A11 @ 12:42:19.4, B9 @ 12:42:19.7 

Not.

Ya da başka bir şekilde yapabilirim - sourceA değerinden sourceB sonra üretilir, ancak 4.0 saniye içinde.

IObservable<string> query = 
    sourceA.Join(sourceB, 
     a => Observable.Timer(TimeSpan.FromSeconds(0.0)), 
     b => Observable.Timer(TimeSpan.FromSeconds(4.0)), 
     (at, bt) => $"{format(at)}, {format(bt)}"); 

Bu bana veriyor: "A" nın tüm s 'ler "B" sonra ortaya' olduğunu

 
A1 @ 12:43:23.8, B0 @ 12:43:21.4 
A1 @ 12:43:23.8, B1 @ 12:43:22.8 
A2 @ 12:43:27.9, B2 @ 12:43:27.3 
A3 @ 12:43:33.6, B3 @ 12:43:29.6 
A4 @ 12:43:36.2, B4 @ 12:43:35.3 
A4 @ 12:43:36.2, B5 @ 12:43:35.5 
A4 @ 12:43:36.2, B6 @ 12:43:35.9 
A5 @ 12:43:43.4, B9 @ 12:43:43.1 
A5 @ 12:43:43.4, B8 @ 12:43:40.6 
A6 @ 12:43:46.5, B10 @ 12:43:43.8 
A6 @ 12:43:46.5, B9 @ 12:43:43.1 
A8 @ 12:43:55.5, B12 @ 12:43:52.4 
A9 @ 12:44:03.8, B13 @ 12:44:01.2 
A12 @ 12:44:09.7, B14 @ 12:44:08.9 
A13 @ 12:44:12.8, B14 @ 12:44:08.9 
A14 @ 12:44:16.0, B15 @ 12:44:13.3 

Not.

Ayrıca sorgu sözdizimi kullanabilirsiniz:

var query = 
    from a in sourceA 
    join b in sourceB 
     on Observable.Timer(TimeSpan.FromSeconds(4.0)) 
     equals Observable.Timer(TimeSpan.FromSeconds(4.0)) 
    select $"{format(a)}, {format(b)}"; 
+0

Vay, çok kapsamlı bir örnek, teşekkür ederim. Bir soru daha: TestScheduler kullanarak nasıl çalıştırılır? Herhangi bir nedenle zaman damgası her zaman aynıdır: https: //gist.github.com/NKnusperer/96f4ee2834d2c2d65d46 – NKnusperer

+0

@NKnusperer - Sadece programlayıcınızı '.Timestamped()' operatörüne ekleyin - '.Timestamp (scheduler);'. – Enigmativity

+0

Bu çalışmaları soğutun. Ancak, zamanla ilgili operatörler için TestScheduler'ı küresel olarak enjekte etmenin ve ardından her çağrıya açık bir şekilde iletmenin daha iyi bir yolu var mı? – NKnusperer