Application requirements:
This should work. The types differ, I didn't want to guess your probably abstract datatypes. You can apply them pretty easily (function parameters, key comparison and Select
statements)
Idea is that for every emited value from a
, we take the first value emited either by b.Where(keys match)
or timeout (presented by Observable.Timer
) and make our Select
based on this information.
I assumed that in timeout cases you also want on OnNext
notification with some error provisioning mechanism.
private IObservable MonitorAB(IObservable a, IObservable b,
TimeSpan threshold)
{
return Observable.Create((obs) =>
{
a = a.Publish().RefCount();
b = b.Publish().RefCount();
return a.Subscribe(i =>
{
Observable.Merge(Observable.Timer(threshold).Select(_ => $"Timeout for A{i}"),
b.Where(j => j == i).Select(_ => $"Got matching B for A{i}"))
.Take(1)
.Subscribe(obs.OnNext);
});
});
}
I tested it like this.
private void Test()
{
var a = Observable.Interval(TimeSpan.FromSeconds(2)).Take(5);
var b = Observable.Interval(TimeSpan.FromSeconds(5)).Take(5);
MonitorAB( a, b, TimeSpan.FromSeconds(13)).Subscribe(Console.WriteLine);
}
EDIT: to test the out of order case, you can flip the B stream e.g.
var b = Observable.Interval(TimeSpan.FromSeconds(2)).Select(i => 4 - i).Take(5);