无法使用FirstAsync获取Rx窗口的第一个窗口

时间:2016-09-16 19:49:34

标签: system.reactive

我想将一个可观察的序列(IObservable)分成几个可观察的序列(标准很复杂,但为了演示,我们可以简单地使用count)。很明显,这需要Window

    private static IObservable<int> GenerateSequence()
    {
        return Observable.Range(1, 5);
    }

    await GenerateSequence()
            .Window(2)
            .Select((w, i) => new {i, w})
            .Do(w => w.w.Dump($"Window {w.i}"));

输出符合预期:

Window 0-->1
Window 0-->2
Window 0-->X
Window 1-->3
Window 1-->4
Window 1-->X
Window 2-->5
Window 2-->X

X标记OnCompleted

现在,出于某种原因,我只想要那些序列中的第一个。因此,FirstAsync

    (await GenerateSequence()
        .Window(2)
        .FirstAsync())
        .Dump("Window");

但奇怪的是,我根本没有输出,好像我从FirstAsync得到的序列完全死了。

我是Rx的新手,所以我完全迷失了为什么以及为什么会在这里发生。

2 个答案:

答案 0 :(得分:1)

修改 你的答案有效。您WindowBuffer替换var t = GenerateSequence() .Buffer(2) .FirstAsync() //.Select(list => list.ToArray()) //If you're particular about Task<int[]> over Task<IList<int>> .ToTask(); 。它们实际上是相同的,除了Buffer用于类似场景。它返回一个列表而不是数组:

.SelectMany(i => i)

另外,.Merge()可以替换为await

旧答案

我通常不会将Rx与GenerateSequence() .Window(2) .FirstAsync() .Subscribe(i => i.Dump("Window")); 混合使用。它显然得到了支持,但似乎......不直观。此代码转储第一个窗口的输出:

GenerateSequence()
    .Window(2)
    .Select(o => o.FirstAsync())
    .Subscribe(i => i.Dump("Window"));

这会转储每个窗口中的第一个项目:

conf.get('prefix')

从你的问题中不清楚你想要哪一个。

答案 1 :(得分:0)

实际上,解决方案非常简单(虽然我仍然没有得到原始代码中发生的情况) - 使用SelectMany来平整序列:

GenerateSequence()
.Window(2)
.FirstAsync()
.Concat()
.Dump("SO");

按预期生产:

SO-->1
SO-->2
SO-->X

然后,实现我的原始目标 - 即更改monad并将结果返回为Task<int[]>

GenerateSequence()
.Window(2)
.FirstAsync()
.Concat()
.ToArray()
.ToTask();