如何与GroupBy聚合并等待结果

时间:2016-10-22 23:23:11

标签: c# rx.net

比如说,我跟踪每位球员为板球名单旅行的距离。我可能有以下对象

  • 旅行(IList腿)
  • 腿(距离,持续时间,玩家和属于旅行)
  • 玩家(属于团队)

我想使用Reactive Extensions聚合此数据。这是我的第一次尝试:

var trips = new List<Trip>();

Observable.Return( trips )
  .SelectMany( trips => trips )
  .SelectMany( trip => trip.legs )
  .GroupBy( leg => leg.player.team )
  .Select( teamLegs => {
    var teamSummary = new {
      team = teamLegs.key,
      distance = 0M,
      duration = 0M
    }

    teamLegs.Sum( x => x.distance ).Subscribe( x => { teamSummary.distance = x; } )
    teamLegs.Sum( x => x.duration ).Subscribe( x => { teamSummary.duration = x; } )

    return teamSummary;
  })
  .Select(teamSummary => {
      // If I try to do something with teamSummary.distance or duration - the above
      // sum is yet to be completed 
  })

  // ToList will make the above sums work, but only if there's only 1 Select statement above
  .ToList()

  .Subscribe(teamSummaries => {
  });

如何确保在第二个Select()语句之前完成总和?

1 个答案:

答案 0 :(得分:0)

可观察的是等待的。如果您等待它,它将等待序列完成,并返回最后一项。

因此,您可以做的是等待结果,而不是订阅。 这样,一旦结果准备好,第一个Select内的块将仅返回。

.Select(async teamLegs =>
    new {
        team = teamLegs.key,
        distance = await teamLegs.Sum(x => x.distance),
        duration = await teamLegs.Sum(x => x.duration)
        })
...

Select语句将返回IObservable<Task<(type of teamSummary)>,因此您可以使用SelectMany(...)来获取IObservable<(type of teamSummary)>