2012-01-14 44 views
0

只需查看Rx加入扩展方法即可。我不能完全弄清楚如何使用它来创建关键连接(使用关系域而不是时域)?Rx加入密钥而非持续时间

var right = Observable.Range(4, 20); 
var left = Observable.Range(0, 30).Where(n => n%2 == 0); 
var e = from n1 in right 
     join n2 in left on ? equals ? 
     select new {n1, n2}; 
e.Subscribe(j => Console.WriteLine(" n1: {0}, n2: {1}", j.n1, j.n2)); 

所需的输出:

n1: 4, n2: 4 
n2: 6, n2: 6 
n3: 8, n2: 8 
... 

不知道是否加入可以采用这种方式......?

编辑

这工作,但它是要做到这一点(并发性,性能)的路吗?

var e = from n1 in right 
     from n2 in left 
     where n1 == n2 
     select new { n1, n2 }; 
+0

谢谢你的帮助。我只是意识到我想在这个问题相同的事情:http://stackoverflow.com/questions/4911465/how-to-join-multiple-iobservable-sequences – lukebuehler 2012-01-16 18:52:58

回答

3

重要的是要记住,观察者是随着时间的推移收集 - 或者说把它看作是一系列事件的另一种方式。因为枚举数据可以被认为是在某个时刻的集合。

加入enumerables是有意义的 - 在进行连接时,所有的值都可供您使用。

使用Rx时它有所不同 - 它几乎就像你需要做某种时间旅行!

因此,每当您尝试在Rx世界中进行“加入”时,您都会说“类似于”一段时间,请记住可观察A上的所有值,并将它们与可观察B期间发生的值进行匹配那个时期“。

Rx中的Join运算符专门用于定义自定义时间段并观察在时间段内发生的事件。

经典的情况是,每当有人进入或离开房间时,都会有一系列事件发生,并且当某个事件(例如灯亮起)发生时,您想知道房间里有谁。

在某些方面,您的第二个查询SelectMany查询只是在两个观察对象的生命周期内发生的连接,而Rx必须记住所有的值以生成匹配。它实际上是一对正在构建的集合,并在添加值时执行连接。

只要输入序列不会太大(仍然可能意味着大但不是太大就可以),并且它们最终终止,那么SelectMany的性能是很好的。使用热点观察值(如点击发生的事件模式)对于执行SelectMany将是一个不好的选择。

所以,如果你有特定的时间段参加 - 使用Join - 但如果你只是想加入两个observable的每个值使用SelectMany

+0

好的答案,我现在意识到,我问略有问题题。我想到的钥匙实际上是时间戳。我基本上想要在每场比赛的时间戳中同步两个观察对象。所以基本上你可以把范围数作为时间戳。而且你是对的,我不想做出这样的选择,因为可能有很多数据。 – lukebuehler 2012-01-16 16:27:47

+0

PS:当你提到房间时,我不得不说这个话题:http://channel9.msdn.com/Shows/Going+Deep/Programming-Streams-of-Coincidence-with-Join-and-GroupJoin-for- RX – lukebuehler 2012-01-16 16:28:45

0

如果它不在时间范围内,为什么不简单地使用Enumerable?