等待后,反应程序不会终止

问题描述 投票:1回答:1

我期望下面的程序能够回显任何按键,直到你点击z,但是当你点击z时它不会终止,并且只会在每次按键时回显。我做错了什么?

using System.Reactive;
using System.Reactive.Linq;

public class Printer : IObserver<char>
{ 
    public void OnNext(char x)
    {
        Console.WriteLine(x);
    }

    public void OnError(Exception x)
    {

    }
    public void OnCompleted()
    {

    }
}

class Program
{
    static IObservable<char> keys = Observable.Defer(() =>Observable.Start(() =>Console.ReadKey().KeyChar)).Repeat(); //https://stackoverflow.com/questions/10675451/iobservable-of-keys-pressed
    public static int Main()
    {
        IObserver<char> x = new Printer();
        keys.Subscribe(x);
        keys.Where(b => b == 'z').Wait();
        return 0;
    }
}
c# system.reactive
1个回答
2
投票

好的,所以两个问题都是分开的:

  1. 你在这里有一个cold observable。只有当你开始观察它产生价值时才会这样。相反,每次订阅它时,它代表一个新流 - 类似于IEnumerable每次尝试获取物品时的评估方式。如果你在Observable.Defer中放置一个断点,你可以清楚地看到这一点。 您可以拥有这两个流share just one subscription to the source,即按键可观察。所以我们将冷观察变为热点。
  2. Wait方法是: 等待可观察序列完成并返回序列的最后一个元素。如果序列以OnError通知终止,则抛出异常。 因此,它将等到序列完成,即,OnCompleted已被调用可观察链。因此,我们使用TakeUntil,以便只有在满足条件时才按顺序完成(按'z')。 public static int Main() { var keys_stream = keys.Publish().RefCount(); // share IObserver<char> x = new Printer(); keys_stream.Subscribe(x); keys_stream.TakeUntil(b => b == 'z').Wait(); //wait until z return 0; }
© www.soinside.com 2019 - 2024. All rights reserved.