等待后反应程序不会终止

时间:2019-04-04 16:17:56

标签: c# system.reactive

我希望下面的程序在您按下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;
    }
}

1 个答案:

答案 0 :(得分:2)

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

  1. 您在这里拥有的是cold observable。 只有当您开始观察它时,它才会产生值。 相反,每次订阅时,它代表一个新流-类似于IEnumerable每次尝试取物品时的评估方式。如果在Observable.Defer内放置一个断点,则可以清楚地看到这一点。

    您可以拥有这两个流share just one subscription to the source,即可以观察到的按键。因此,我们将可观测的寒冷转化为炎热的天气。

  2. Wait方法是:

      

    等待可观察到的序列 complete ,并返回的最后一个元素   序列。如果序列以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;
        }