Reactive-Extensions を使用して、どちらか一方のタイプの状況を処理する必要があります。
受信しているイベントが 2 つあります (A または B)。イベント A に続いて 2 秒以内にイベント B が発生すると、C を生成したいと思います。A の後に B が続かない場合は、D を生成したいと思います。
それをRxで表現する方法はありますか??
ありがとう
Reactive-Extensions を使用して、どちらか一方のタイプの状況を処理する必要があります。
受信しているイベントが 2 つあります (A または B)。イベント A に続いて 2 秒以内にイベント B が発生すると、C を生成したいと思います。A の後に B が続かない場合は、D を生成したいと思います。
それをRxで表現する方法はありますか??
ありがとう
Here's one way you can do it:
Observable.Merge(eventA, eventB)
.Timestamp()
.Buffer(2 /*items*/,1 /*at a time*/)
.SelectMany(x => {
if (x[1].Timestamp - x[0].Timestamp < TimeSpan.FromSeconds(2.0) &&
x[0].Value.EventType == "A" && x[1].Value.EventType == "B") {
return Observable.Return(new C());
}
if (x[0].Value.EventType == "A" && x[1].Value.EventType != "B") {
return Observable.Return(new D());
}
return Observable.Empty<AnEvent>();
});
SelectMany は、代替オブザーバブルを返す Timeout のオーバーロードとともに、あなたが説明したことを実行できるはずです。
Dim obsA = Observable.Interval(TimeSpan.FromSeconds(1)) 'whatever your source is
Dim obsB = Observable.Interval(TimeSpan.FromSeconds(0.5)) 'whatever your source is
'replace with your actual C/D generation functions
Dim final = From a In obsA
From b In obsB.Select(Function(i) "C" & a.ToString()) _
.Timeout(TimeSpan.FromSeconds(2),
Observable.Return("D" & a.ToString())) _
.Take(1)
Select b
Amb
これは、組み込みの演算子を使用することでかなり簡単に思えます。
最初に次のように定義しますobsC
。obsD
var obsC = Observable.Return('C');
var obsD = Observable.Delay(
Observable.Return('D'),
TimeSpan.FromSeconds(2.0));
ここで、「B」、次に「C」のオブザーバブルが必要です。最後の「B」の後に一度だけ「C」が必要です。2 つの「B」が発生した場合、最新のものだけが必要です。ここにあります:
var obsBC =
obsB
.Select(_ => obsC)
.Switch()
.Take(1);
Amb
次に、演算子を使用してすべてをまとめた最後のクエリを示します。
var query =
from a in obsA
from cd in Observable.Amb(obsBC, obsD)
select cd;
私のテストでは、このクエリが機能することが示されています。しかし、これらすべての場合と同様に、「B」の前に「A」が 2 つ入った場合にどうすればよいかは明確ではありません。「D」/「C」または「C」/「C」、または単に「D」または「C」を取得できますか? 必要な動作によっては、クエリを変更する必要がある場合があります。