【问题标题】:Reactive extensions: Zip operator but different反应式扩展:Zip 运算符,但不同
【发布时间】:2014-10-08 17:22:21
【问题描述】:

这不是现实生活中的例子(这段代码可能无法编译),但我试图让它比我实际遇到的问题简单一点。

假设我有图像集合:

private void IEnumerable<Image> GetImages()
{
    foreach (var filename in GetFilenames())
    {
         yield return Image.LoadFile(filename);
    }
}

我想显示由用户按“空格”驱动的幻灯片:

var images = Observable.FromEvent(form, "KeyPress")
  .Where(e => e.KeyCode == KeyCode.Space)
  .Zip(GetImages.ToObservable(), (k, i) => i);

而且这种作品。当按下空格时,它会发出下一张图像。问题是它实际上以全速加载它们,因此它们被缓冲并消耗大量内存(以及加载时的处理能力)。 我可以将过滤后的按键输入 GetImages 和那里的压缩,但我不会保留 GetImages 的纯度。

有什么方法可以防止在不需要的情况下提前枚举 enumerable.ToObservable()?

另一个例子(这个会编译):

var observable = 
    Observable.Interval(TimeSpan.FromSeconds(1))
    .Zip(
        Observable.Range(0, 1000000).Do(x => Console.WriteLine("produced {0}", x)), 
        (_, v) => v
    );

var subscription = observable.Subscribe(x => Console.WriteLine("consumed {0}", x));

Console.WriteLine("Press <enter>...");
Console.ReadLine();

它会(提前)生成很多“已生产”,但每秒只会“消耗”一个。

【问题讨论】:

    标签: c# system.reactive


    【解决方案1】:

    Dave 坚持从 IEnumerable&lt;T&gt; 提取图像的想法很可靠,但您可以更轻松地实现相同的目标 - 只需从您的代码中删除 ToObservable()

    var images = Observable.FromEvent(form, "KeyPress")
                           .Where(e => e.KeyCode == KeyCode.Space)
                           .Zip(GetImages() /* No ToObservable() here! */, (k, i) => i);
    

    Zip 的这种重载将在您按键时驱动可枚举的图像。

    【讨论】:

    • +1。我只是错过了一个明确的陈述: observable.Zip(enumerable) 是关于以 observable 的速度提供 enumerable (您可以从这个答案中暗示,但没有明确说明)。
    • +1 Rx 中的另一个“隐藏”重载,我以前从未使用过这个。应该在发布前检查过载列表——新手错误;-)
    • 正如他们所说 - 我去过那里,做到了。毫无疑问会很快再次访问。 :)
    【解决方案2】:

    改为从枚举器中提取怎么样?

    var keys = Observable.FromEventPattern<KeyPressEventArgs>(form, "KeyPress");
    var slides = (from key in keys
                  where key.EventArgs.KeyCode == KeyCode.Space
                  select key)
                 .Publish(spaces => 
                  {
                    var images = GetImages().GetEnumerator();
    
                    return spaces.TakeUntil(from _ in spaces
                                            where !images.MoveNext()
                                            select Unit.Default)
                                 .Select(_ => images.Current);
                  });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-20
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多