C# 反应式程序不';等待之后不要终止

C# 反应式程序不';等待之后不要终止,c#,system.reactive,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 OnE

我希望下面的程序在您点击
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;
    }
}
使用系统。无功;
使用System.Reactive.Linq;
公共类打印机:IObserver
{ 
公共void OnNext(字符x)
{
控制台写入线(x);
}
公共无效单错误(例外x)
{
}
未完成的公共无效()
{
}
}
班级计划
{
静态IObservable key=Observable.Defer(()=>Observable.Start(()=>Console.ReadKey().KeyChar)).Repeat()//https://stackoverflow.com/questions/10675451/iobservable-of-keys-pressed
公共静态int Main()
{
IObserver x=新打印机();
密钥。订阅(x);
其中(b=>b=='z').Wait();
返回0;
}
}

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

  • 你这里的是一本书。 只有当你开始观察它时,它才会产生价值。 相反,每次您订阅它时,它代表一个新的流-类似于每次尝试获取项目时
    IEnumerable
    的计算方式。如果在
    可观察的.Defer中放置断点,则可以清楚地看到这一点

    您可以看到这两个流,即按键可观察。所以我们将冷态的可见光转换成热态的可见光

  • Wait
    方法是:

    等待可观察序列完成,并返回该序列的最后一个元素 顺序。如果序列以OnError通知终止,则异常 被抛出

    因此,它将等待序列完成,也就是说,一个
    OnCompleted
    已被调用到可观察链中。因此,我们使用
    TakeUntil
    ,这样序列只在满足条件时完成(按“z”)

    publicstaticintmain()
    {
    var keys_stream=keys.Publish().RefCount();//共享
    IObserver x=新打印机();
    密钥\流订阅(x);
    keys_stream.TakeUntil(b=>b='z').Wait();//等待到z
    返回0;
    }
    

  • 您正在创建多个订阅。如果您想共享按键,您需要发布可观察的。
        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;
        }