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
İş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 & sourceB
sourceA
ü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)}";
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
@NKnusperer - Sadece programlayıcınızı '.Timestamped()' operatörüne ekleyin - '.Timestamp (scheduler);'. – Enigmativity
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