RX挑战5复杂事件处理使用LINQ语言集成查询(Spoiler Alert)

时间:2012-09-05 11:15:33

标签: c# system.reactive

在RX网站的complex event processing workshop中,使用缓冲区完成了挑战5。我有一个使用LINQ点或lamba表示法的解决方案。出于兴趣,我想将其转换为LINQ语言集成查询表示法。

挑战和我的代码如下。由于某些原因result2无法正常工作,它会使UI无响应并且输出看起来被截断。这是一个时髦的东西,是我的查询,你能解决它吗?

挑战(下载here

IObservable<object> Query(IObservable<StockQuote> quotes)
{
    // TODO: Change the query below to compute the average high and average low over
    //       the past five trading days as well as the current close and date.
    // HINT: Try using Buffer.

    return from quote in quotes
           where quote.Symbol == "MSFT"
           select new { quote.Close, quote.Date };
}

我的解决方案

IObservable<object> Query(IObservable<StockQuote> quotes)
{
    // TODO: Change the query below to compute the average high and average low over
    //       the past five trading days as well as the current close and date.
    // HINT: Try using Buffer.

    var result1 = quotes.Where(qt => qt.Symbol == "MSFT").Buffer(5, 1).Select(quoteList =>
    {
        var avg = quoteList.Average(qt => qt.Close);
        return new { avg, quoteList.Last().Close, quoteList.Last().Date };
    });

    var result2 = from quote in quotes
                  where quote.Symbol == "MSFT"
                  from quoteList in quotes.Buffer(5, 1)
                  let avg = quoteList.Average(qt => qt.Close)
                  select new { avg, quoteList.Last().Close, quoteList.Last().Date };

    return result2;
}

3 个答案:

答案 0 :(得分:1)

两种解决方案都多次订阅引号(甚至超过两次 - 记住多个子句会导致引擎盖下的SelectMany调用),所以那里已经出现了问题:-)。再试一次。

答案 1 :(得分:0)

我认为查询看起来应该更像这样:

        var result =
            from quote in quotes
            where quote.Symbol == "MSFT"
            from quoteList in quotes.Buffer(5, 1)
            let avgHigh = quoteList.Average(qt => qt.High)
            let avgLow = quoteList.Average(qt => qt.Low)
            select new { avgHigh, avgLow, quote.Close, quote.Date };

但这与你的只有很小的区别 - 只有当quoteList.Last()做&amp;时才需要quote。问题是High&amp;的平均值。 Low,而不是Close

据我所知,问题在于图表而不是Rx组件。我认为图表经常重绘,以至于它正在阻塞。

答案 2 :(得分:0)

问题要求同时绘制两个图形(当前,平均)。 我不相信可以使用绑定monad(SelectMany)来独立地组成问题所指定的那两个流的最新值。

quotes.Buffer向下的理解将与缓冲流的速率绑定。

可替换地:

        quotes = quotes.Publish().RefCount();
        return Observable.CombineLatest
            (
                first: quotes,
                second: quotes.Buffer(5, 1).Select(
                        buffer => new { High = buffer.Average(q => q.High), Low = buffer.Average(q => q.Low) }),
                resultSelector: (l, r) => new { l.Close, l.Date, r.High, r.Low }
            );

以与源相同的速率移动,从而产生平滑的图形。