Reactive Extensions将两个IObservable组合成一个

时间:2014-10-28 20:03:09

标签: system.reactive

我正在尝试将包含请求信息的IObservable与包含响应信息的IObservable组合在一起。请求和响应信息都包含Id和日期时间形式的时间戳。请求中的Id将与响应中的Id匹配。

我需要根据Id组合两个流,并计算Request的时间戳和Response的时间戳之间经过的时间。实现这一目标的最佳方法是什么:

2 个答案:

答案 0 :(得分:3)

你可以巧合加入。

from request in requests             // 1
join response in responses           // 2
on responses.Where(response => response.Id == request.Id) // 1,3
equals Observable.Empty<Unit>()      // 2
where request.Id == response.Id      // 4
select response.Time - request.Time  // 5

这样想:

  1. 为每个请求创建一个窗口。
  2. 将每个响应投射到每个请求窗口中。
  3. 当响应与请求匹配时,请关闭该请求窗口。
  4. 对于每个请求,请忽略所有不匹配的响应。
  5. 投射匹配响应的时差。
  6. <强>更新

    请求窗口由from打开,并由on关闭。

    响应窗口由join打开,并由equals关闭。 equals指定的响应持续时间为Empty,因此响应实际上不是窗口 - 它们被视为点事件,只需将其投影到当前打开的任何请求窗口中。

    #3需要Where运算符,因为它定义了每个请求的持续时间;即,它指示请求窗口何时关闭,即具有匹配ID的响应何时到达。

    由于#3,

    #4是必需的。考虑一下 - 我们将每个响应与当前打开的每个请求窗口交叉加入。请求窗口仅在匹配响应到达时关闭。这意味着每个不匹配的响应都与每个请求配对,但您只关心最后一个响应 - 匹配的响应。

答案 1 :(得分:0)

如果您没有并发请求,Zip可能是您正在寻找的运营商:

http://rxmarbles.com/#zip

Zip将在一个序列中组合两个observable,以一个由最慢的observable组合定义的速率生成元素。

如果你有并发请求,你应该尝试一种不需要你组合两个observable的不同方法。例如,您可以将请求ID和DateTime存储在ConcurrentDictionary中,并订阅可观察的响应,您可以在其中查找ConcurrentDictionary中的相应请求(请不要忘记在读取后删除该条目)。