反应性扩展:Zip运算符但不同

Mil*_*ski 2 c# system.reactive

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

假设我有图像集:

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

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

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

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

有没有办法防止枚举.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();
Run Code Online (Sandbox Code Playgroud)

它将产生大量"生产"(提前),但每秒仅消耗一个"消耗".

Jam*_*rld 6

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

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

当您按下按键时,Zip的这种重载将驱动图像可枚举.