Rx GroupBy - 如何获取分组值?

时间:2015-07-20 23:38:43

标签: c# .net-4.5 system.reactive

根据React 2014上的演示文稿,其中“一切都是一个流”并查看Reactive Trader源代码,我想我会尝试重新使用我的一些旧代码来遵循这种模式,但我有点难过。

我有两种具有以下签名的方法:

public static IObservable<OrderDto> GetOrderStream(string name)
public static IObservable<PriceDto> GetPriceStream(string exchange, string security)

两种方法都使用Observable.Create来包装一些事件,并在创建的Observable上使用Publish()RefCount()

每个OrderDto都包含用于交换和安全的字段。我想通过Exchange和安全性对订单进行分组,以便我可以从单独的流中请求定价信息。对于我的最终结果,我想打印每个订单以及订单中交易所/证券的当前价格。

对于订单,我有以下内容:

var orders = Observable.Defer(() => GetOrderStream("FNZCTEST"))
                                                .GroupBy(o => new { o.Exchange, o.Security })
                                                .Publish()
                                                .RefCount();

如果我使用:

var j = from order in orders
                from o in order
                from price in GetPriceStream(order.Key.Exchange, order.Key.Security).Materialize()
                select new { Order = o, Price = price };

IDisposable disposable = j.Subscribe(x => Console.WriteLine("{0} : {1}", x.Order, x.Price.HasValue ? x.Price.Value : new PriceDto()));

我得到了所需的输出,但是对于相同的Exchange / Security重复调用GetPriceStream(即每个组不会一次)。

如果我将其更改为

var j = from order in orders
        from price in GetPriceStream(order.Key.Exchange, order.Key.Security).Materialize()
        select new { Price = price };

IDisposable disposable = j.Subscribe(x => Console.WriteLine("{0} : {1}", "", x.Price.HasValue ? x.Price.Value : new PriceDto()));

然后按照我的预期为每个组调用一次GetPriceStream。我的问题是 - 如何获得这种期望的行为并访问组中的每个OrderDto,以便我可以一起输出订单和价格。

1 个答案:

答案 0 :(得分:0)

这里有一些事情对我没有意义。我不明白你为什么要做.Defer(...)以及为什么要做.Publish().RefCount()

此外,您正在对结果进行分组,然后展平它们。为什么不把它们保留原样呢?

最后,当.Materialize()没有产生实际值时,您似乎正在使用GetPriceStream以某种方式处理这种情况。

因此,考虑到所有这些,这似乎是您最需要的查询:

var query =
    from order in GetOrderStream("FNZCTEST")
    from price in GetPriceStream(order.Exchange, order.Security)
        .DefaultIfEmpty(new PriceDto())
    select new
    {
        Order = order,
        Price = price,
    };

IDisposable disposable =
    query.Subscribe(x => Console.WriteLine("{0} : {1}", x.Order, x.Price));

现在,Observable.Create的实施也可能会让您感到悲伤。所以,如果可以的话,如果你可以在问题的最后添加实现,那就太棒了。